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
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 {
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 {

View File

@ -197,13 +197,6 @@ func TestDecode_structureArray(t *testing.T) {
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{
Keys: []KeyPolicy{
KeyPolicy{
@ -225,7 +218,21 @@ func TestDecode_structureArray(t *testing.T) {
},
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected)
files := []string{
"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:
STRING COLON value
{
value := $3
if obj, ok := value.(ast.ObjectNode); ok {
obj.K = $1
value = obj
}
$$ = ast.AssignmentNode{
K: $1,
Value: $3,
Value: value,
}
}

View File

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