json: pass to clean up objcet lists
This commit is contained in:
parent
60534579be
commit
e3ed2553ca
@ -159,7 +159,7 @@ func TestDecode_interface(t *testing.T) {
|
|||||||
"structure_list.json",
|
"structure_list.json",
|
||||||
false,
|
false,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"foo": []interface{}{
|
"foo": []map[string]interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": 7,
|
"key": 7,
|
||||||
},
|
},
|
||||||
|
112
json/parse.go
112
json/parse.go
@ -65,41 +65,13 @@ func flattenObjects(node ast.Node) {
|
|||||||
item := frontier[n-1]
|
item := frontier[n-1]
|
||||||
frontier = frontier[:n-1]
|
frontier = frontier[:n-1]
|
||||||
|
|
||||||
// We only care if the value of this item is an object
|
switch v := item.Val.(type) {
|
||||||
ot, ok := item.Val.(*ast.ObjectType)
|
case *ast.ObjectType:
|
||||||
if !ok {
|
items, frontier = flattenObjectType(v, item, items, frontier)
|
||||||
|
case *ast.ListType:
|
||||||
|
items, frontier = flattenListType(v, item, items, frontier)
|
||||||
|
default:
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// All the elements of this object must also be objects!
|
|
||||||
match := true
|
|
||||||
for _, item := range ot.List.Items {
|
|
||||||
if _, ok := item.Val.(*ast.ObjectType); !ok {
|
|
||||||
match = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !match {
|
|
||||||
items = append(items, item)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Great! We have a match go through all the items and flatten
|
|
||||||
for _, subitem := range ot.List.Items {
|
|
||||||
// Copy the new key
|
|
||||||
keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys))
|
|
||||||
copy(keys, item.Keys)
|
|
||||||
copy(keys[len(item.Keys):], subitem.Keys)
|
|
||||||
|
|
||||||
// Add it to the frontier so that we can recurse
|
|
||||||
frontier = append(frontier, &ast.ObjectItem{
|
|
||||||
Keys: keys,
|
|
||||||
Assign: item.Assign,
|
|
||||||
Val: subitem.Val,
|
|
||||||
LeadComment: item.LeadComment,
|
|
||||||
LineComment: item.LineComment,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,3 +86,75 @@ func flattenObjects(node ast.Node) {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flattenListType(
|
||||||
|
ot *ast.ListType,
|
||||||
|
item *ast.ObjectItem,
|
||||||
|
items []*ast.ObjectItem,
|
||||||
|
frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) {
|
||||||
|
// All the elements of this object must also be objects!
|
||||||
|
for _, subitem := range ot.List {
|
||||||
|
if _, ok := subitem.(*ast.ObjectType); !ok {
|
||||||
|
items = append(items, item)
|
||||||
|
return items, frontier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Great! We have a match go through all the items and flatten
|
||||||
|
for _, elem := range ot.List {
|
||||||
|
// This won't fail since we verified it earlier
|
||||||
|
ot := elem.(*ast.ObjectType)
|
||||||
|
|
||||||
|
// Go over all the subitems and merge them in
|
||||||
|
for _, subitem := range ot.List.Items {
|
||||||
|
// Copy the new key
|
||||||
|
keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys))
|
||||||
|
copy(keys, item.Keys)
|
||||||
|
copy(keys[len(item.Keys):], subitem.Keys)
|
||||||
|
|
||||||
|
// Add it to the frontier so that we can recurse
|
||||||
|
frontier = append(frontier, &ast.ObjectItem{
|
||||||
|
Keys: keys,
|
||||||
|
Assign: item.Assign,
|
||||||
|
Val: subitem.Val,
|
||||||
|
LeadComment: item.LeadComment,
|
||||||
|
LineComment: item.LineComment,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return items, frontier
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenObjectType(
|
||||||
|
ot *ast.ObjectType,
|
||||||
|
item *ast.ObjectItem,
|
||||||
|
items []*ast.ObjectItem,
|
||||||
|
frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) {
|
||||||
|
// All the elements of this object must also be objects!
|
||||||
|
for _, subitem := range ot.List.Items {
|
||||||
|
if _, ok := subitem.Val.(*ast.ObjectType); !ok {
|
||||||
|
items = append(items, item)
|
||||||
|
return items, frontier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Great! We have a match go through all the items and flatten
|
||||||
|
for _, subitem := range ot.List.Items {
|
||||||
|
// Copy the new key
|
||||||
|
keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys))
|
||||||
|
copy(keys, item.Keys)
|
||||||
|
copy(keys[len(item.Keys):], subitem.Keys)
|
||||||
|
|
||||||
|
// Add it to the frontier so that we can recurse
|
||||||
|
frontier = append(frontier, &ast.ObjectItem{
|
||||||
|
Keys: keys,
|
||||||
|
Assign: item.Assign,
|
||||||
|
Val: subitem.Val,
|
||||||
|
LeadComment: item.LeadComment,
|
||||||
|
LineComment: item.LineComment,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return items, frontier
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user