Expose Transform() as a method on a field Selector

This commit is contained in:
Clayton Coleman 2015-03-22 18:49:23 -04:00
parent 319f5b280a
commit bac4689942

View File

@ -35,6 +35,10 @@ type Selector interface {
// requires. // requires.
RequiresExactMatch(field string) (value string, found bool) RequiresExactMatch(field string) (value string, found bool)
// Transform returns a new copy of the selector after TransformFunc has been
// applied to the entire selector, or an error if fn returns an error.
Transform(fn TransformFunc) (Selector, error)
// String returns a human readable string that represents this selector. // String returns a human readable string that represents this selector.
String() string String() string
} }
@ -63,6 +67,14 @@ func (t *hasTerm) RequiresExactMatch(field string) (value string, found bool) {
return "", false return "", false
} }
func (t *hasTerm) Transform(fn TransformFunc) (Selector, error) {
field, value, err := fn(t.field, t.value)
if err != nil {
return nil, err
}
return &hasTerm{field, value}, nil
}
func (t *hasTerm) String() string { func (t *hasTerm) String() string {
return fmt.Sprintf("%v=%v", t.field, t.value) return fmt.Sprintf("%v=%v", t.field, t.value)
} }
@ -83,6 +95,14 @@ func (t *notHasTerm) RequiresExactMatch(field string) (value string, found bool)
return "", false return "", false
} }
func (t *notHasTerm) Transform(fn TransformFunc) (Selector, error) {
field, value, err := fn(t.field, t.value)
if err != nil {
return nil, err
}
return &notHasTerm{field, value}, nil
}
func (t *notHasTerm) String() string { func (t *notHasTerm) String() string {
return fmt.Sprintf("%v!=%v", t.field, t.value) return fmt.Sprintf("%v!=%v", t.field, t.value)
} }
@ -125,6 +145,18 @@ func (t andTerm) RequiresExactMatch(field string) (string, bool) {
return "", false return "", false
} }
func (t andTerm) Transform(fn TransformFunc) (Selector, error) {
next := make([]Selector, len([]Selector(t)))
for i, s := range []Selector(t) {
n, err := s.Transform(fn)
if err != nil {
return nil, err
}
next[i] = n
}
return andTerm(next), nil
}
func (t andTerm) String() string { func (t andTerm) String() string {
var terms []string var terms []string
for _, q := range t { for _, q := range t {
@ -183,31 +215,19 @@ func parseSelector(selector string, fn TransformFunc) (Selector, error) {
continue continue
} }
if lhs, rhs, ok := try(part, "!="); ok { if lhs, rhs, ok := try(part, "!="); ok {
lhs, rhs, err := fn(lhs, rhs)
if err != nil {
return nil, err
}
items = append(items, &notHasTerm{field: lhs, value: rhs}) items = append(items, &notHasTerm{field: lhs, value: rhs})
} else if lhs, rhs, ok := try(part, "=="); ok { } else if lhs, rhs, ok := try(part, "=="); ok {
lhs, rhs, err := fn(lhs, rhs)
if err != nil {
return nil, err
}
items = append(items, &hasTerm{field: lhs, value: rhs}) items = append(items, &hasTerm{field: lhs, value: rhs})
} else if lhs, rhs, ok := try(part, "="); ok { } else if lhs, rhs, ok := try(part, "="); ok {
lhs, rhs, err := fn(lhs, rhs)
if err != nil {
return nil, err
}
items = append(items, &hasTerm{field: lhs, value: rhs}) items = append(items, &hasTerm{field: lhs, value: rhs})
} else { } else {
return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part) return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
} }
} }
if len(items) == 1 { if len(items) == 1 {
return items[0], nil return items[0].Transform(fn)
} }
return andTerm(items), nil return andTerm(items).Transform(fn)
} }
// OneTermEqualSelector returns an object that matches objects where one field/field equals one value. // OneTermEqualSelector returns an object that matches objects where one field/field equals one value.