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()) }