Decode into flat structures for objects

This commit is contained in:
Mitchell Hashimoto 2014-08-03 13:09:08 -07:00
parent 58215e2ffa
commit 96e92c5213
5 changed files with 63 additions and 2 deletions

View File

@ -1,10 +1,12 @@
TEST?=./...
default: test
fmt: hcl/y.go json/y.go
go fmt ./...
test: hcl/y.go json/y.go
go test ./...
go test $(TEST) $(TESTARGS)
hcl/y.go: hcl/parse.y
cd hcl && \

View File

@ -3,6 +3,7 @@ package hcl
import (
"fmt"
"reflect"
"strconv"
"github.com/hashicorp/hcl/ast"
)
@ -145,6 +146,19 @@ func (d *decoder) decodeInterface(name string, raw ast.Node, result reflect.Valu
}
func (d *decoder) decodeMap(name string, raw ast.Node, result reflect.Value) error {
// If we have a list, then we decode each element into a map
if list, ok := raw.(ast.ListNode); ok {
for i, elem := range list.Elem {
fieldName := fmt.Sprintf("%s.%d", name, i)
err := d.decode(fieldName, elem, result)
if err != nil {
return err
}
}
return nil
}
obj, ok := raw.(ast.ObjectNode)
if !ok {
return fmt.Errorf("%s: not an object type", name)
@ -257,10 +271,13 @@ func (d *decoder) decodeString(name string, raw ast.Node, result reflect.Value)
}
switch n.Type {
case ast.ValueTypeInt:
result.Set(reflect.ValueOf(
strconv.FormatInt(int64(n.Value.(int)), 10)))
case ast.ValueTypeString:
result.Set(reflect.ValueOf(n.Value.(string)))
default:
return fmt.Errorf("%s: unknown type %s", name, n.Type)
return fmt.Errorf("%s: unknown type to string: %s", name, n.Type)
}
return nil

View File

@ -117,3 +117,23 @@ func TestDecode_equal(t *testing.T) {
}
}
}
func TestDecode_flatMap(t *testing.T) {
var val map[string]map[string]string
err := Decode(&val, testReadFile(t, "structure_flatmap.hcl"))
if err != nil {
t.Fatalf("err: %s", err)
}
expected := map[string]map[string]string{
"foo": map[string]string{
"foo": "bar",
"key": "7",
},
}
if !reflect.DeepEqual(val, expected) {
t.Fatalf("Actual: %#v\n\nExpected: %#v", val, expected)
}
}

View File

@ -1,4 +1,19 @@
package hcl
import (
"io/ioutil"
"path/filepath"
"testing"
)
// This is the directory where our test fixtures are.
const fixtureDir = "./test-fixtures"
func testReadFile(t *testing.T, n string) string {
d, err := ioutil.ReadFile(filepath.Join(fixtureDir, n))
if err != nil {
t.Fatalf("err: %s", err)
}
return string(d)
}

View File

@ -0,0 +1,7 @@
foo {
key = 7
}
foo {
foo = "bar"
}