Don't double-nest lists of objects

This commit is contained in:
Mitchell Hashimoto 2014-08-21 13:32:31 -07:00
parent 2b53be2ffe
commit 65159dc252
4 changed files with 54 additions and 2 deletions

View File

@ -31,7 +31,9 @@ func DecodeObject(out interface{}, n *hcl.Object) error {
return d.decode("root", n, reflect.ValueOf(out).Elem())
}
type decoder struct{}
type decoder struct{
last, current reflect.Kind
}
func (d *decoder) decode(name string, o *hcl.Object, result reflect.Value) error {
k := result
@ -45,6 +47,11 @@ func (d *decoder) decode(name string, o *hcl.Object, result reflect.Value) error
}
}
// Keep track of the last known type and the current since we use
// some context to determine things.
d.last = d.current
d.current = k.Kind()
switch k.Kind() {
case reflect.Bool:
return d.decodeBool(name, o, result)
@ -112,7 +119,10 @@ func (d *decoder) decodeInterface(name string, o *hcl.Object, result reflect.Val
switch o.Type {
case hcl.ValueTypeObject:
if name == "root" {
// If we're at the root or we're directly within a slice, then we
// decode objects into map[string]interface{}, otherwise we decode
// them into lists.
if d.last == reflect.Invalid || d.last == reflect.Slice {
var temp map[string]interface{}
tempVal := reflect.ValueOf(temp)
result := reflect.MakeMap(

View File

@ -97,9 +97,38 @@ func TestDecode_interface(t *testing.T) {
},
},
},
{
"structure_list.hcl",
false,
map[string]interface{}{
"foo": []map[string]interface{}{
map[string]interface{}{
"key": 7,
},
map[string]interface{}{
"key": 12,
},
},
},
},
{
"structure_list.json",
false,
map[string]interface{}{
"foo": []map[string]interface{}{
map[string]interface{}{
"key": 7,
},
map[string]interface{}{
"key": 12,
},
},
},
},
}
for _, tc := range cases {
if tc.File != "empty.hcl" { continue }
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.File))
if err != nil {
t.Fatalf("err: %s", err)

View File

@ -0,0 +1,6 @@
foo {
key = 7
}
foo {
key = 12
}

View File

@ -0,0 +1,7 @@
{
"foo": [{
"key": 7
}, {
"key": 12
}]
}