1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
package segments
import (
"fmt"
"strings"
)
// [.=foo], [.^foo], [.$foo], [.%foo]
type StringValueSearch struct {
operator byte
pattern string
}
func ParseStringValueSearchSegment(s string) (YamlPathSegment, error) {
operator := s[2]
pattern := s[3 : len(s)-1]
return &StringValueSearch{
operator: operator,
pattern: pattern,
}, nil
}
func (s *StringValueSearch) NavigateMap(m map[string]interface{}) (interface{}, error) {
for k, v := range m {
if s.valueMatches(k) {
return v, nil
}
}
return nil, fmt.Errorf("could not find matching key in hash for pattern '[.%s%s]", string(s.operator), s.pattern)
}
func (s *StringValueSearch) NavigateArray(l []interface{}) (interface{}, error) {
for _, i := range l {
switch v := i.(type) {
case string:
if s.valueMatches(v) {
return v, nil
}
continue
default:
return nil, fmt.Errorf("could not search for value '%s' as list does not contain strings", s.pattern)
}
}
return nil, fmt.Errorf("could not find match for search part '[.%s%s]'", string(s.operator), s.pattern)
}
func (s *StringValueSearch) valueMatches(v string) bool {
switch s.operator {
case '^':
return strings.HasPrefix(v, s.pattern)
case '$':
return strings.HasSuffix(v, s.pattern)
case '%':
return strings.Contains(v, s.pattern)
case '=':
return v == s.pattern
default:
return false
}
}
|