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