40 lines
1.0 KiB
Go
40 lines
1.0 KiB
Go
|
package q
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"reflect"
|
||
|
)
|
||
|
|
||
|
// ErrUnknownField is returned when an unknown field is passed.
|
||
|
var ErrUnknownField = errors.New("unknown field")
|
||
|
|
||
|
type fieldMatcherDelegate struct {
|
||
|
FieldMatcher
|
||
|
Field string
|
||
|
}
|
||
|
|
||
|
// NewFieldMatcher creates a Matcher for a given field.
|
||
|
func NewFieldMatcher(field string, fm FieldMatcher) Matcher {
|
||
|
return fieldMatcherDelegate{Field: field, FieldMatcher: fm}
|
||
|
}
|
||
|
|
||
|
// FieldMatcher can be used in NewFieldMatcher as a simple way to create the
|
||
|
// most common Matcher: A Matcher that evaluates one field's value.
|
||
|
// For more complex scenarios, implement the Matcher interface directly.
|
||
|
type FieldMatcher interface {
|
||
|
MatchField(v interface{}) (bool, error)
|
||
|
}
|
||
|
|
||
|
func (r fieldMatcherDelegate) Match(i interface{}) (bool, error) {
|
||
|
v := reflect.Indirect(reflect.ValueOf(i))
|
||
|
return r.MatchValue(&v)
|
||
|
}
|
||
|
|
||
|
func (r fieldMatcherDelegate) MatchValue(v *reflect.Value) (bool, error) {
|
||
|
field := v.FieldByName(r.Field)
|
||
|
if !field.IsValid() {
|
||
|
return false, ErrUnknownField
|
||
|
}
|
||
|
return r.MatchField(field.Interface())
|
||
|
}
|