1package cache
2
3import (
4 "strings"
5
6 "github.com/MichaelMure/git-bug/bug"
7)
8
9// Filter is a functor that match a subset of bugs
10type Filter func(excerpt *BugExcerpt) bool
11
12// StatusFilter return a Filter that match a bug status
13func StatusFilter(query string) (Filter, error) {
14 status, err := bug.StatusFromString(query)
15 if err != nil {
16 return nil, err
17 }
18
19 return func(excerpt *BugExcerpt) bool {
20 return excerpt.Status == status
21 }, nil
22}
23
24// AuthorFilter return a Filter that match a bug author
25func AuthorFilter(query string) Filter {
26 return func(excerpt *BugExcerpt) bool {
27 query = strings.ToLower(query)
28
29 return strings.Contains(strings.ToLower(excerpt.Author.Name), query) ||
30 strings.Contains(strings.ToLower(excerpt.Author.Login), query)
31 }
32}
33
34// LabelFilter return a Filter that match a label
35func LabelFilter(label string) Filter {
36 return func(excerpt *BugExcerpt) bool {
37 for _, l := range excerpt.Labels {
38 if string(l) == label {
39 return true
40 }
41 }
42 return false
43 }
44}
45
46// NoLabelFilter return a Filter that match the absence of labels
47func NoLabelFilter() Filter {
48 return func(excerpt *BugExcerpt) bool {
49 return len(excerpt.Labels) == 0
50 }
51}
52
53// Filters is a collection of Filter that implement a complex filter
54type Filters struct {
55 Status []Filter
56 Author []Filter
57 Label []Filter
58 NoFilters []Filter
59}
60
61// Match check if a bug match the set of filters
62func (f *Filters) Match(excerpt *BugExcerpt) bool {
63 if match := f.orMatch(f.Status, excerpt); !match {
64 return false
65 }
66
67 if match := f.orMatch(f.Author, excerpt); !match {
68 return false
69 }
70
71 if match := f.orMatch(f.Label, excerpt); !match {
72 return false
73 }
74
75 if match := f.andMatch(f.NoFilters, excerpt); !match {
76 return false
77 }
78
79 return true
80}
81
82// Check if any of the filters provided match the bug
83func (*Filters) orMatch(filters []Filter, excerpt *BugExcerpt) bool {
84 if len(filters) == 0 {
85 return true
86 }
87
88 match := false
89 for _, f := range filters {
90 match = match || f(excerpt)
91 }
92
93 return match
94}
95
96// Check if all of the filters provided match the bug
97func (*Filters) andMatch(filters []Filter, excerpt *BugExcerpt) bool {
98 if len(filters) == 0 {
99 return true
100 }
101
102 match := true
103 for _, f := range filters {
104 match = match && f(excerpt)
105 }
106
107 return match
108}