5
5
"maps"
6
6
"slices"
7
7
"sort"
8
+ "strconv"
8
9
"strings"
9
10
)
10
11
@@ -15,7 +16,7 @@ type Predicate[T any] func(item T, filterValue string) bool
15
16
type Options [T any ] struct {
16
17
matchers map [string ]Predicate [T ]
17
18
unsupported map [string ]struct {}
18
- logFunc func (key , val string )
19
+ logFunc func (key string , val string )
19
20
}
20
21
21
22
// Option configures filter Options.
@@ -61,11 +62,20 @@ func NewOptions[T any](opt ...Option[T]) (Options[T], error) {
61
62
return opts , nil
62
63
}
63
64
64
- // ValueProvider extracts a single string value from an item of type T.
65
- type ValueProvider [T any ] func (T ) string
65
+ // Provider is a generic function type that encapsulates the logic for extracting
66
+ // a value of type V from an filterValue of type T. It provides a flexible way to
67
+ // retrieve specific data from various types of structures or sources.
68
+ type Provider [T any , V any ] func (T ) V
66
69
67
- // ValuesProvider extracts a slice of string values from an item of type T.
68
- type ValuesProvider [T any ] func (T ) []string
70
+ // BoolValueProvider extracts a single boolean value from an item of type T.
71
+ type BoolValueProvider [T any ] Provider [T , bool ]
72
+
73
+ // StringValueProvider extracts a single string value from an item of type T.
74
+ type StringValueProvider [T any ] Provider [T , string ]
75
+
76
+ // StringValuesProvider extracts a slice of string values from an item of type T.
77
+ // type ValuesProvider[T any] func(T) []string
78
+ type StringValuesProvider [T any ] Provider [T , []string ]
69
79
70
80
// Equals returns a Predicate that checks if the value extracted by the provider
71
81
// exactly matches the filter value (case-insensitive, normalized).
@@ -74,22 +84,39 @@ type ValuesProvider[T any] func(T) []string
74
84
//
75
85
// predicate := Equals(options.SourceProvider),
76
86
// result := predicate(pkg, "github") // true if pkg.Source equals "github"
77
- func Equals [T any ](provider ValueProvider [T ]) Predicate [T ] {
87
+ func Equals [T any ](provider StringValueProvider [T ]) Predicate [T ] {
78
88
return func (item T , val string ) bool {
79
89
actual := NormalizeString (provider (item ))
80
90
expected := NormalizeString (val )
81
91
return actual == expected
82
92
}
83
93
}
84
94
95
+ // EqualsBool returns a Predicate that checks if the value extracted by the provider
96
+ // matches the parsed boolean representation of the filter value.
97
+ //
98
+ // Example:
99
+ //
100
+ // predicate := EqualsBool(options.IsOfficialProvider),
101
+ // result := predicate(pkg, "true") // true if pkg.IsOfficial is true
102
+ func EqualsBool [T any ](provider BoolValueProvider [T ]) Predicate [T ] {
103
+ return func (item T , val string ) bool {
104
+ parsedVal , err := strconv .ParseBool (NormalizeString (val ))
105
+ if err != nil {
106
+ return false
107
+ }
108
+ return provider (item ) == parsedVal
109
+ }
110
+ }
111
+
85
112
// Partial returns a Predicate that checks if the value extracted by the provider
86
113
// contains the filter value as a substring (case-insensitive, normalized).
87
114
//
88
115
// Example:
89
116
//
90
117
// predicate := Partial(options.VersionProvider),
91
118
// result := predicate(pkg, "1.2") // true if pkg.Version contains "1.2"
92
- func Partial [T any ](provider ValueProvider [T ]) Predicate [T ] {
119
+ func Partial [T any ](provider StringValueProvider [T ]) Predicate [T ] {
93
120
return func (item T , val string ) bool {
94
121
actual := NormalizeString (provider (item ))
95
122
expected := NormalizeString (val )
@@ -105,7 +132,7 @@ func Partial[T any](provider ValueProvider[T]) Predicate[T] {
105
132
//
106
133
// predicate := PartialAll(options.ToolsProvider),
107
134
// result := predicate(pkg, "get_current_time,convert_time") // true if pkg.Tools contains values with "get_current_time" and "convert_time" as substrings
108
- func PartialAll [T any ](provider ValuesProvider [T ]) Predicate [T ] {
135
+ func PartialAll [T any ](provider StringValuesProvider [T ]) Predicate [T ] {
109
136
return func (item T , val string ) bool {
110
137
required := NormalizeSlice (strings .Split (val , "," ))
111
138
actual := NormalizeSlice (provider (item ))
@@ -128,13 +155,13 @@ func PartialAll[T any](provider ValuesProvider[T]) Predicate[T] {
128
155
129
156
// EqualsAny returns a Predicate that checks if *ANY* of the values from the supplied providers are equal to the
130
157
// filter value (case-insensitive, normalized).
131
- // Functionally similar to Equals, but operates on one or more ValueProvider .
158
+ // Functionally similar to Equals, but operates on one or more StringValueProvider .
132
159
//
133
160
// Example:
134
161
//
135
162
// predicate := EqualsAny(options.ToolsProvider),
136
163
// result := predicate(pkg, "get_current_time,convert_time") // true if pkg.Tools contains values "get_current_time" or "convert_time"
137
- func EqualsAny [T any ](providers ... ValueProvider [T ]) Predicate [T ] {
164
+ func EqualsAny [T any ](providers ... StringValueProvider [T ]) Predicate [T ] {
138
165
return func (item T , val string ) bool {
139
166
q := NormalizeString (val )
140
167
for _ , p := range providers {
@@ -155,7 +182,7 @@ func EqualsAny[T any](providers ...ValueProvider[T]) Predicate[T] {
155
182
//
156
183
// predicate := HasOnly(options.ToolsProvider),
157
184
// result := predicate(pkg, "get_current_time,convert_time") // true if pkg.Tools only contains tools from the list
158
- func HasOnly [T any ](provider ValuesProvider [T ]) Predicate [T ] {
185
+ func HasOnly [T any ](provider StringValuesProvider [T ]) Predicate [T ] {
159
186
return func (item T , val string ) bool {
160
187
required := strings .Split (val , "," )
161
188
expected := make (map [string ]struct {}, len (required ))
@@ -181,7 +208,7 @@ func HasOnly[T any](provider ValuesProvider[T]) Predicate[T] {
181
208
//
182
209
// predicate := HasAll(options.ToolsProvider),
183
210
// result := predicate(pkg, "get_current_time,convert_time") // true if pkg.Tools contains both "get_current_time" and "convert_time"
184
- func HasAll [T any ](provider ValuesProvider [T ]) Predicate [T ] {
211
+ func HasAll [T any ](provider StringValuesProvider [T ]) Predicate [T ] {
185
212
return func (item T , val string ) bool {
186
213
required := NormalizeSlice (strings .Split (val , "," ))
187
214
actual := provider (item )
@@ -208,7 +235,7 @@ func HasAll[T any](provider ValuesProvider[T]) Predicate[T] {
208
235
//
209
236
// predicate := HasAny(options.ToolsProvider),
210
237
// result := predicate(pkg, "get_current_time,convert_time") // true if pkg.Tools contains either "get_current_time" or "convert_time"
211
- func HasAny [T any ](provider ValuesProvider [T ]) Predicate [T ] {
238
+ func HasAny [T any ](provider StringValuesProvider [T ]) Predicate [T ] {
212
239
return func (item T , val string ) bool {
213
240
required := NormalizeSlice (strings .Split (val , "," ))
214
241
allowed := make (map [string ]struct {}, len (required ))
@@ -256,7 +283,7 @@ func WithUnsupportedKeys[T any](keys ...string) Option[T] {
256
283
}
257
284
258
285
// WithLogFunc sets a log function which will be used to log info if unsupported keys are encountered.
259
- func WithLogFunc [T any ](logFunc func (key , val string )) Option [T ] {
286
+ func WithLogFunc [T any ](logFunc func (key string , val string )) Option [T ] {
260
287
return func (o * Options [T ]) error {
261
288
if logFunc != nil {
262
289
o .logFunc = logFunc
0 commit comments