decode JSON equally

This commit is contained in:
Mitchell Hashimoto 2014-08-08 15:58:34 -07:00
parent 61bd5db85c
commit 437eb0d851
5 changed files with 74 additions and 29 deletions

View File

@ -451,8 +451,15 @@ func (d *decoder) decodeStruct(name string, raw ast.Node, result reflect.Value)
// Create the field name and decode // Create the field name and decode
fieldName = fmt.Sprintf("%s.%s", name, fieldName) fieldName = fmt.Sprintf("%s.%s", name, fieldName)
for _, elem := range elems { for _, elem := range elems {
// If it is a sub-object, go through all the fields
if obj, ok := elem.(ast.ObjectNode); ok { if obj, ok := elem.(ast.ObjectNode); ok {
elem = obj.Elem[0].Value 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 { if err := d.decode(fieldName, elem, field); err != nil {

View File

@ -197,13 +197,6 @@ func TestDecode_structureArray(t *testing.T) {
Keys []KeyPolicy `hcl:"key"` Keys []KeyPolicy `hcl:"key"`
} }
var actual Policy
err := Decode(&actual, testReadFile(t, "decode_policy.hcl"))
if err != nil {
t.Fatalf("err: %s", err)
}
expected := Policy{ expected := Policy{
Keys: []KeyPolicy{ Keys: []KeyPolicy{
KeyPolicy{ KeyPolicy{
@ -225,7 +218,21 @@ func TestDecode_structureArray(t *testing.T) {
}, },
} }
if !reflect.DeepEqual(actual, expected) { files := []string{
t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected) "decode_policy.hcl",
"decode_policy.json",
}
for _, f := range files {
var actual Policy
err := Decode(&actual, testReadFile(t, f))
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("Input: %s\n\nActual: %#v\n\nExpected: %#v", f, actual, expected)
}
} }
} }

View File

@ -69,9 +69,15 @@ members:
pair: pair:
STRING COLON value STRING COLON value
{ {
value := $3
if obj, ok := value.(ast.ObjectNode); ok {
obj.K = $1
value = obj
}
$$ = ast.AssignmentNode{ $$ = ast.AssignmentNode{
K: $1, K: $1,
Value: $3, Value: value,
} }
} }

View File

@ -65,7 +65,7 @@ const jsonEofCode = 1
const jsonErrCode = 2 const jsonErrCode = 2
const jsonMaxDepth = 200 const jsonMaxDepth = 200
//line parse.y:178 //line parse.y:184
//line yacctab:1 //line yacctab:1
var jsonExca = []int{ var jsonExca = []int{
@ -395,13 +395,19 @@ jsondefault:
case 6: case 6:
//line parse.y:71 //line parse.y:71
{ {
value := jsonS[jsonpt-0].item
if obj, ok := value.(ast.ObjectNode); ok {
obj.K = jsonS[jsonpt-2].str
value = obj
}
jsonVAL.assign = ast.AssignmentNode{ jsonVAL.assign = ast.AssignmentNode{
K: jsonS[jsonpt-2].str, K: jsonS[jsonpt-2].str,
Value: jsonS[jsonpt-0].item, Value: value,
} }
} }
case 7: case 7:
//line parse.y:80 //line parse.y:86
{ {
jsonVAL.item = ast.LiteralNode{ jsonVAL.item = ast.LiteralNode{
Type: ast.ValueTypeString, Type: ast.ValueTypeString,
@ -409,22 +415,22 @@ jsondefault:
} }
} }
case 8: case 8:
//line parse.y:87 //line parse.y:93
{ {
jsonVAL.item = jsonS[jsonpt-0].item jsonVAL.item = jsonS[jsonpt-0].item
} }
case 9: case 9:
//line parse.y:91 //line parse.y:97
{ {
jsonVAL.item = jsonS[jsonpt-0].obj jsonVAL.item = jsonS[jsonpt-0].obj
} }
case 10: case 10:
//line parse.y:95 //line parse.y:101
{ {
jsonVAL.item = jsonS[jsonpt-0].array jsonVAL.item = jsonS[jsonpt-0].array
} }
case 11: case 11:
//line parse.y:99 //line parse.y:105
{ {
jsonVAL.item = ast.LiteralNode{ jsonVAL.item = ast.LiteralNode{
Type: ast.ValueTypeBool, Type: ast.ValueTypeBool,
@ -432,7 +438,7 @@ jsondefault:
} }
} }
case 12: case 12:
//line parse.y:106 //line parse.y:112
{ {
jsonVAL.item = ast.LiteralNode{ jsonVAL.item = ast.LiteralNode{
Type: ast.ValueTypeBool, Type: ast.ValueTypeBool,
@ -440,7 +446,7 @@ jsondefault:
} }
} }
case 13: case 13:
//line parse.y:113 //line parse.y:119
{ {
jsonVAL.item = ast.LiteralNode{ jsonVAL.item = ast.LiteralNode{
Type: ast.ValueTypeNil, Type: ast.ValueTypeNil,
@ -448,27 +454,27 @@ jsondefault:
} }
} }
case 14: case 14:
//line parse.y:122 //line parse.y:128
{ {
jsonVAL.array = ast.ListNode{} jsonVAL.array = ast.ListNode{}
} }
case 15: case 15:
//line parse.y:126 //line parse.y:132
{ {
jsonVAL.array = ast.ListNode{Elem: jsonS[jsonpt-1].list} jsonVAL.array = ast.ListNode{Elem: jsonS[jsonpt-1].list}
} }
case 16: case 16:
//line parse.y:132 //line parse.y:138
{ {
jsonVAL.list = []ast.Node{jsonS[jsonpt-0].item} jsonVAL.list = []ast.Node{jsonS[jsonpt-0].item}
} }
case 17: case 17:
//line parse.y:136 //line parse.y:142
{ {
jsonVAL.list = append(jsonS[jsonpt-2].list, jsonS[jsonpt-0].item) jsonVAL.list = append(jsonS[jsonpt-2].list, jsonS[jsonpt-0].item)
} }
case 18: case 18:
//line parse.y:142 //line parse.y:148
{ {
jsonVAL.item = ast.LiteralNode{ jsonVAL.item = ast.LiteralNode{
Type: ast.ValueTypeInt, Type: ast.ValueTypeInt,
@ -476,7 +482,7 @@ jsondefault:
} }
} }
case 19: case 19:
//line parse.y:149 //line parse.y:155
{ {
fs := fmt.Sprintf("%d.%s", jsonS[jsonpt-1].num, jsonS[jsonpt-0].str) fs := fmt.Sprintf("%d.%s", jsonS[jsonpt-1].num, jsonS[jsonpt-0].str)
f, err := strconv.ParseFloat(fs, 64) f, err := strconv.ParseFloat(fs, 64)
@ -490,17 +496,17 @@ jsondefault:
} }
} }
case 20: case 20:
//line parse.y:164 //line parse.y:170
{ {
jsonVAL.num = jsonS[jsonpt-0].num * -1 jsonVAL.num = jsonS[jsonpt-0].num * -1
} }
case 21: case 21:
//line parse.y:168 //line parse.y:174
{ {
jsonVAL.num = jsonS[jsonpt-0].num jsonVAL.num = jsonS[jsonpt-0].num
} }
case 22: case 22:
//line parse.y:174 //line parse.y:180
{ {
jsonVAL.str = strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10) jsonVAL.str = strconv.FormatInt(int64(jsonS[jsonpt-0].num), 10)
} }

View File

@ -0,0 +1,19 @@
{
"key": {
"": {
"policy": "read"
},
"foo/": {
"policy": "write"
},
"foo/bar/": {
"policy": "read"
},
"foo/bar/baz": {
"policy": "deny"
}
}
}