Decode into pointers

This commit is contained in:
Mitchell Hashimoto 2014-08-03 17:17:17 -07:00
parent daed1fd01d
commit ae8e4f9b5e
4 changed files with 72 additions and 4 deletions

View File

@ -69,11 +69,18 @@ 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) []KeyedNode {
result := make([]KeyedNode, 0, 1)
func (n ObjectNode) Get(k string) []Node {
result := make([]Node, 0, 1)
for _, elem := range n.Elem {
if elem.Key() == k {
result = append(result, elem)
if elem.Key() != k {
continue
}
switch n := elem.(type) {
case AssignmentNode:
result = append(result, n.Value)
default:
panic("unknown type")
}
}

View File

@ -70,3 +70,25 @@ func TestObjectNode_accept(t *testing.T) {
t.Fatalf("bad: %#v", v.Nodes)
}
}
func TestObjectNodeGet(t *testing.T) {
n := ObjectNode{
K: "foo",
Elem: []KeyedNode{
AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}},
AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}},
AssignmentNode{K: "foo", Value: LiteralNode{Value: "baz"}},
},
}
expected := []Node{
LiteralNode{Value: "foo"},
LiteralNode{Value: "baz"},
}
actual := n.Get("foo")
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}

View File

@ -58,6 +58,8 @@ func (d *decoder) decode(name string, n ast.Node, result reflect.Value) error {
return d.decodeInterface(name, n, result)
case reflect.Map:
return d.decodeMap(name, n, result)
case reflect.Ptr:
return d.decodePtr(name, n, result)
case reflect.Slice:
return d.decodeSlice(name, n, result)
case reflect.String:
@ -238,6 +240,20 @@ func (d *decoder) decodeMap(name string, raw ast.Node, result reflect.Value) err
return nil
}
func (d *decoder) decodePtr(name string, raw ast.Node, result reflect.Value) error {
// Create an element of the concrete (non pointer) type and decode
// into that. Then set the value of the pointer to this type.
resultType := result.Type()
resultElemType := resultType.Elem()
val := reflect.New(resultElemType)
if err := d.decode(name, raw, reflect.Indirect(val)); err != nil {
return err
}
result.Set(val)
return nil
}
func (d *decoder) decodeSlice(name string, raw ast.Node, result reflect.Value) error {
n, ok := raw.(ast.ListNode)
if !ok {

View File

@ -160,3 +160,26 @@ func TestDecode_structure(t *testing.T) {
t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected)
}
}
func TestDecode_structurePtr(t *testing.T) {
type V struct {
Key int
Foo string
}
var actual *V
err := Decode(&actual, testReadFile(t, "flat.hcl"))
if err != nil {
t.Fatalf("err: %s", err)
}
expected := &V{
Key: 7,
Foo: "bar",
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected)
}
}