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 cleaned := strings.TrimFunc(query, func(r rune) bool {
27 return r == '"' || r == '\''
28 })
29
30 return func(excerpt *BugExcerpt) bool {
31 return excerpt.Author.Match(cleaned)
32 }
33}
34
35// LabelFilter return a Filter that match a label
36func LabelFilter(label string) Filter {
37 return func(excerpt *BugExcerpt) bool {
38 for _, l := range excerpt.Labels {
39 if string(l) == label {
40 return true
41 }
42 }
43 return false
44 }
45}
46
47// NoLabelFilter return a Filter that match the absence of labels
48func NoLabelFilter() Filter {
49 return func(excerpt *BugExcerpt) bool {
50 return len(excerpt.Labels) == 0
51 }
52}
53
54// Filters is a collection of Filter that implement a complex filter
55type Filters struct {
56 Status []Filter
57 Author []Filter
58 Label []Filter
59 NoFilters []Filter
60}
61
62// Match check if a bug match the set of filters
63func (f *Filters) Match(excerpt *BugExcerpt) bool {
64 if match := f.orMatch(f.Status, excerpt); !match {
65 return false
66 }
67
68 if match := f.orMatch(f.Author, excerpt); !match {
69 return false
70 }
71
72 if match := f.orMatch(f.Label, excerpt); !match {
73 return false
74 }
75
76 if match := f.andMatch(f.NoFilters, excerpt); !match {
77 return false
78 }
79
80 return true
81}
82
83// Check if any of the filters provided match the bug
84func (*Filters) orMatch(filters []Filter, excerpt *BugExcerpt) bool {
85 if len(filters) == 0 {
86 return true
87 }
88
89 match := false
90 for _, f := range filters {
91 match = match || f(excerpt)
92 }
93
94 return match
95}
96
97// Check if all of the filters provided match the bug
98func (*Filters) andMatch(filters []Filter, excerpt *BugExcerpt) bool {
99 if len(filters) == 0 {
100 return true
101 }
102
103 match := true
104 for _, f := range filters {
105 match = match && f(excerpt)
106 }
107
108 return match
109}