From 96e92c5213f34a828deae21eeeccd2e4dc4130ff Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 3 Aug 2014 13:09:08 -0700 Subject: [PATCH] Decode into flat structures for objects --- Makefile | 4 +++- decoder.go | 19 ++++++++++++++++++- decoder_test.go | 20 ++++++++++++++++++++ hcl_test.go | 15 +++++++++++++++ test-fixtures/structure_flatmap.hcl | 7 +++++++ 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 test-fixtures/structure_flatmap.hcl diff --git a/Makefile b/Makefile index 02fe07e4..34452479 100644 --- a/Makefile +++ b/Makefile @@ -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 && \ diff --git a/decoder.go b/decoder.go index de9f2698..61d3ade7 100644 --- a/decoder.go +++ b/decoder.go @@ -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 diff --git a/decoder_test.go b/decoder_test.go index 94973d2a..60715847 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -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) + } +} diff --git a/hcl_test.go b/hcl_test.go index dfefd28b..31dff7c9 100644 --- a/hcl_test.go +++ b/hcl_test.go @@ -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) +} diff --git a/test-fixtures/structure_flatmap.hcl b/test-fixtures/structure_flatmap.hcl new file mode 100644 index 00000000..fcf689e1 --- /dev/null +++ b/test-fixtures/structure_flatmap.hcl @@ -0,0 +1,7 @@ +foo { + key = 7 +} + +foo { + foo = "bar" +}