summaryrefslogtreecommitdiffstats
path: root/src/go/pkg/matcher/logical.go
blob: af07be8f4e79133e1ed85ac713c8a81a2f9ad72b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// SPDX-License-Identifier: GPL-3.0-or-later

package matcher

type (
	trueMatcher  struct{}
	falseMatcher struct{}
	andMatcher   struct{ lhs, rhs Matcher }
	orMatcher    struct{ lhs, rhs Matcher }
	negMatcher   struct{ Matcher }
)

var (
	matcherT trueMatcher
	matcherF falseMatcher
)

// TRUE returns a matcher which always returns true
func TRUE() Matcher {
	return matcherT
}

// FALSE returns a matcher which always returns false
func FALSE() Matcher {
	return matcherF
}

// Not returns a matcher which positive the sub-matcher's result
func Not(m Matcher) Matcher {
	switch m {
	case TRUE():
		return FALSE()
	case FALSE():
		return TRUE()
	default:
		return negMatcher{m}
	}
}

// And returns a matcher which returns true only if all of it's sub-matcher return true
func And(lhs, rhs Matcher, others ...Matcher) Matcher {
	var matcher Matcher
	switch lhs {
	case TRUE():
		matcher = rhs
	case FALSE():
		matcher = FALSE()
	default:
		switch rhs {
		case TRUE():
			matcher = lhs
		case FALSE():
			matcher = FALSE()
		default:
			matcher = andMatcher{lhs, rhs}
		}
	}
	if len(others) > 0 {
		return And(matcher, others[0], others[1:]...)
	}
	return matcher
}

// Or returns a matcher which returns true if any of it's sub-matcher return true
func Or(lhs, rhs Matcher, others ...Matcher) Matcher {
	var matcher Matcher
	switch lhs {
	case TRUE():
		matcher = TRUE()
	case FALSE():
		matcher = rhs
	default:
		switch rhs {
		case TRUE():
			matcher = TRUE()
		case FALSE():
			matcher = lhs
		default:
			matcher = orMatcher{lhs, rhs}
		}
	}
	if len(others) > 0 {
		return Or(matcher, others[0], others[1:]...)
	}
	return matcher
}

func (trueMatcher) Match(_ []byte) bool       { return true }
func (trueMatcher) MatchString(_ string) bool { return true }

func (falseMatcher) Match(_ []byte) bool       { return false }
func (falseMatcher) MatchString(_ string) bool { return false }

func (m andMatcher) Match(b []byte) bool       { return m.lhs.Match(b) && m.rhs.Match(b) }
func (m andMatcher) MatchString(s string) bool { return m.lhs.MatchString(s) && m.rhs.MatchString(s) }

func (m orMatcher) Match(b []byte) bool       { return m.lhs.Match(b) || m.rhs.Match(b) }
func (m orMatcher) MatchString(s string) bool { return m.lhs.MatchString(s) || m.rhs.MatchString(s) }

func (m negMatcher) Match(b []byte) bool       { return !m.Matcher.Match(b) }
func (m negMatcher) MatchString(s string) bool { return !m.Matcher.MatchString(s) }