-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathfilter.go
84 lines (72 loc) · 1.7 KB
/
filter.go
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
package main
import (
"strings"
)
func tokenizeFilterQuery(query string) []string {
tokens := []string{}
var currentToken string
var inQuotes bool
var quoteChar rune
for i := 0; i < len(query); i++ {
c := rune(query[i])
// If we're not in quotes and encounter a quote, we enter 'quote mode'
if !inQuotes && (c == '"' || c == '\'') {
inQuotes = true
quoteChar = c
continue
}
// If we are in quotes and encounter the same quoteChar, we exit 'quote mode'
if inQuotes && c == quoteChar {
inQuotes = false
continue
}
// If we're not in quotes and see a space, that's a token boundary
if !inQuotes && c == ' ' {
if currentToken != "" {
tokens = append(tokens, currentToken)
currentToken = ""
}
continue
}
// Otherwise, accumulate the character
currentToken += string(c)
}
// Append the last token if non-empty
if currentToken != "" {
tokens = append(tokens, currentToken)
}
return tokens
}
func evaluateFilterQuery(query string, input string) (bool, error) {
input = strings.ToLower(input)
tokens := tokenizeFilterQuery(strings.ToLower(query))
matches := true
for _, token := range tokens {
if strings.Contains(token, "|") {
// OR logic
terms := strings.Split(token, "|")
orMatch := false
for _, term := range terms {
if strings.Contains(input, term) {
orMatch = true
break
}
}
matches = matches && orMatch
} else if strings.HasPrefix(token, "!") {
// NOT logic
term := strings.TrimPrefix(token, "!")
if strings.Contains(input, term) {
matches = false
break
}
} else {
// AND logic (implicit)
if !strings.Contains(input, token) {
matches = false
break
}
}
}
return matches, nil
}