From 719a177dba6d54b8fe15cdff29e3b35314700c3f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 11 Aug 2014 16:51:52 -0700 Subject: [PATCH] decoding structs a bit --- decoder.go | 25 +++++-------------------- hcl/object.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/decoder.go b/decoder.go index 646fc4a..3c726ab 100644 --- a/decoder.go +++ b/decoder.go @@ -334,11 +334,10 @@ func (d *decoder) decodeStruct(name string, o *hcl.Object, result reflect.Value) } } - //usedKeys := make(map[string]struct{}) + usedKeys := make(map[string]struct{}) decodedFields := make([]string, 0, len(fields)) decodedFieldsVal := make([]reflect.Value, 0) unusedKeysVal := make([]reflect.Value, 0) - /* for fieldType, field := range fields { if !field.IsValid() { // This should never happen @@ -374,8 +373,8 @@ func (d *decoder) decodeStruct(name string, o *hcl.Object, result reflect.Value) } // Find the element matching this name - elems := obj.Get(fieldName, true) - if len(elems) == 0 { + obj := o.Get(fieldName, true) + if obj == nil { continue } @@ -384,26 +383,12 @@ func (d *decoder) decodeStruct(name string, o *hcl.Object, result reflect.Value) // Create the field name and decode fieldName = fmt.Sprintf("%s.%s", name, fieldName) - for _, elem := range elems { - // If it is a sub-object, go through all the fields - if obj, ok := elem.(ast.ObjectNode); ok { - for _, elem := range obj.Elem { - if err := d.decode(fieldName, elem.Value, field); err != nil { - return err - } - } - - continue - } - - if err := d.decode(fieldName, elem, field); err != nil { - return err - } + if err := d.decode(fieldName, obj, field); err != nil { + return err } decodedFields = append(decodedFields, fieldType.Name) } - */ for _, v := range decodedFieldsVal { v.Set(reflect.ValueOf(decodedFields)) diff --git a/hcl/object.go b/hcl/object.go index 1ca9482..ff6e365 100644 --- a/hcl/object.go +++ b/hcl/object.go @@ -1,5 +1,9 @@ package hcl +import ( + "strings" +) + // ValueType is an enum represnting the type of a value in // a LiteralNode. type ValueType byte @@ -24,6 +28,38 @@ type Object struct { Next *Object } +// Get gets all the objects that match the given key. +// +// It returns the resulting objects as a single Object structure with +// the linked list populated. +func (o *Object) Get(k string, insensitive bool) *Object { + if o.Type != ValueTypeObject { + return nil + } + + var current, result *Object + m := o.Value.(map[string]*Object) + for _, o := range m { + if o.Key != k { + if !insensitive || !strings.EqualFold(o.Key, k) { + continue + } + } + + o2 := *o + o2.Next = nil + if result == nil { + result = &o2 + current = result + } else { + current.Next = &o2 + current = current.Next + } + } + + return result +} + // ObjectList is a list of objects. type ObjectList []*Object