55 "maps"
66 "slices"
77 "sort"
8+ "strconv"
89 "strings"
910)
1011
@@ -15,7 +16,7 @@ type Predicate[T any] func(item T, filterValue string) bool
1516type Options [T any ] struct {
1617 matchers map [string ]Predicate [T ]
1718 unsupported map [string ]struct {}
18- logFunc func (key , val string )
19+ logFunc func (key string , val string )
1920}
2021
2122// Option configures filter Options.
@@ -61,11 +62,20 @@ func NewOptions[T any](opt ...Option[T]) (Options[T], error) {
6162 return opts , nil
6263}
6364
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
6669
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 ]
6979
7080// Equals returns a Predicate that checks if the value extracted by the provider
7181// exactly matches the filter value (case-insensitive, normalized).
@@ -74,22 +84,39 @@ type ValuesProvider[T any] func(T) []string
7484//
7585// predicate := Equals(options.SourceProvider),
7686// 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 ] {
7888 return func (item T , val string ) bool {
7989 actual := NormalizeString (provider (item ))
8090 expected := NormalizeString (val )
8191 return actual == expected
8292 }
8393}
8494
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+
85112// Partial returns a Predicate that checks if the value extracted by the provider
86113// contains the filter value as a substring (case-insensitive, normalized).
87114//
88115// Example:
89116//
90117// predicate := Partial(options.VersionProvider),
91118// 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 ] {
93120 return func (item T , val string ) bool {
94121 actual := NormalizeString (provider (item ))
95122 expected := NormalizeString (val )
@@ -105,7 +132,7 @@ func Partial[T any](provider ValueProvider[T]) Predicate[T] {
105132//
106133// predicate := PartialAll(options.ToolsProvider),
107134// 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 ] {
109136 return func (item T , val string ) bool {
110137 required := NormalizeSlice (strings .Split (val , "," ))
111138 actual := NormalizeSlice (provider (item ))
@@ -128,13 +155,13 @@ func PartialAll[T any](provider ValuesProvider[T]) Predicate[T] {
128155
129156// EqualsAny returns a Predicate that checks if *ANY* of the values from the supplied providers are equal to the
130157// 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 .
132159//
133160// Example:
134161//
135162// predicate := EqualsAny(options.ToolsProvider),
136163// 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 ] {
138165 return func (item T , val string ) bool {
139166 q := NormalizeString (val )
140167 for _ , p := range providers {
@@ -155,7 +182,7 @@ func EqualsAny[T any](providers ...ValueProvider[T]) Predicate[T] {
155182//
156183// predicate := HasOnly(options.ToolsProvider),
157184// 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 ] {
159186 return func (item T , val string ) bool {
160187 required := strings .Split (val , "," )
161188 expected := make (map [string ]struct {}, len (required ))
@@ -181,7 +208,7 @@ func HasOnly[T any](provider ValuesProvider[T]) Predicate[T] {
181208//
182209// predicate := HasAll(options.ToolsProvider),
183210// 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 ] {
185212 return func (item T , val string ) bool {
186213 required := NormalizeSlice (strings .Split (val , "," ))
187214 actual := provider (item )
@@ -208,7 +235,7 @@ func HasAll[T any](provider ValuesProvider[T]) Predicate[T] {
208235//
209236// predicate := HasAny(options.ToolsProvider),
210237// 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 ] {
212239 return func (item T , val string ) bool {
213240 required := NormalizeSlice (strings .Split (val , "," ))
214241 allowed := make (map [string ]struct {}, len (required ))
@@ -256,7 +283,7 @@ func WithUnsupportedKeys[T any](keys ...string) Option[T] {
256283}
257284
258285// 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 ] {
260287 return func (o * Options [T ]) error {
261288 if logFunc != nil {
262289 o .logFunc = logFunc
0 commit comments