case insensitive Get

This commit is contained in:
Mitchell Hashimoto 2014-08-03 17:57:54 -07:00
parent 8c0a6c555f
commit a095771be9
3 changed files with 17 additions and 30 deletions

View File

@ -1,5 +1,9 @@
package ast
import (
"strings"
)
// ValueType is an enum represnting the type of a value in
// a LiteralNode.
type ValueType byte
@ -69,12 +73,14 @@ func (n ObjectNode) Accept(v Visitor) {
// Get returns all the elements of this object with the given key.
// This is a case-sensitive search.
func (n ObjectNode) Get(k string) []Node {
func (n ObjectNode) Get(k string, insensitive bool) []Node {
result := make([]Node, 0, 1)
for _, elem := range n.Elem {
if elem.Key() != k {
if !insensitive || !strings.EqualFold(elem.Key(), k) {
continue
}
}
switch n := elem.(type) {
case AssignmentNode:

View File

@ -86,7 +86,7 @@ func TestObjectNodeGet(t *testing.T) {
LiteralNode{Value: "baz"},
}
actual := n.Get("foo")
actual := n.Get("foo", false)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)

View File

@ -419,40 +419,21 @@ func (d *decoder) decodeStruct(name string, raw ast.Node, result reflect.Value)
}
// Find the element matching this name
var elem ast.Node
elemKey := fieldName
if elems := obj.Get(fieldName); len(elems) > 0 {
elem = elems[len(elems)-1]
} else {
// Do a slower search by iterating over each key and
// doing case-insensitive search.
for _, v := range obj.Elem {
if strings.EqualFold(v.Key(), fieldName) {
elem = v
elemKey = v.Key()
break
}
}
if elem == nil {
// No key matching this field.
elems := obj.Get(fieldName, true)
if len(elems) == 0 {
continue
}
}
// Make sure we get the value of the element
if an, ok := elem.(ast.AssignmentNode); ok {
elem = an.Value
}
// Track the used key
usedKeys[elemKey] = struct{}{}
usedKeys[fieldName] = struct{}{}
// Create the field name and decode
fieldName = fmt.Sprintf("%s.%s", name, fieldName)
for _, elem := range elems {
if err := d.decode(fieldName, elem, field); err != nil {
return err
}
}
decodedFields = append(decodedFields, fieldType.Name)
}