encoder: inline tables create map in nil interface (#496)

Co-authored-by: Thomas Pelletier <pelletier.thomas@gmail.com>
This commit is contained in:
Cameron Moore
2021-04-09 08:02:00 -05:00
committed by GitHub
parent e1f035461b
commit 466bfe8664
3 changed files with 35 additions and 6 deletions
+8
View File
@@ -159,6 +159,14 @@ func ensureValueIndexable(t target) error {
var sliceInterfaceType = reflect.TypeOf([]interface{}{})
var mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
func ensureMapIfInterface(x target) {
v := x.get()
if v.Kind() == reflect.Interface && v.IsNil() {
newElement := reflect.MakeMap(mapStringInterfaceType)
x.set(newElement)
}
}
func setString(t target, v string) error {
f := t.get()
+3 -5
View File
@@ -120,11 +120,7 @@ func (d *decoder) fromParser(p *parser, v interface{}) error {
// looks like a table. Otherwise the information
// of a table is lost, and marshal cannot do the
// round trip.
v := current.get()
if v.Kind() == reflect.Interface && v.IsNil() {
newElement := reflect.MakeMap(mapStringInterfaceType)
current.set(newElement)
}
ensureMapIfInterface(current)
}
case ast.ArrayTable:
current, found, err = d.scopeWithArrayTable(root, node.Key())
@@ -381,6 +377,8 @@ func unmarshalFloat(x target, node ast.Node) error {
func (d *decoder) unmarshalInlineTable(x target, node ast.Node) error {
assertNode(ast.InlineTable, node)
ensureMapIfInterface(x)
it := node.Children()
for it.Next() {
n := it.Node()
+24 -1
View File
@@ -296,6 +296,17 @@ B = "data"`,
}
},
},
{
desc: "standard empty table",
input: `[A]`,
gen: func() test {
var v map[string]interface{}
return test{
target: &v,
expected: &map[string]interface{}{`A`: map[string]interface{}{}},
}
},
},
{
desc: "inline table",
input: `Name = {First = "hello", Last = "world"}`,
@@ -316,6 +327,17 @@ B = "data"`,
}
},
},
{
desc: "inline empty table",
input: `A = {}`,
gen: func() test {
var v map[string]interface{}
return test{
target: &v,
expected: &map[string]interface{}{`A`: map[string]interface{}{}},
}
},
},
{
desc: "inline table inside array",
input: `Names = [{First = "hello", Last = "world"}, {First = "ab", Last = "cd"}]`,
@@ -713,6 +735,7 @@ type Integer484 struct {
func (i Integer484) MarshalText() ([]byte, error) {
return []byte(strconv.Itoa(i.Value)), nil
}
func (i *Integer484) UnmarshalText(data []byte) error {
conv, err := strconv.Atoi(string(data))
if err != nil {
@@ -895,7 +918,7 @@ func TestIssue287(t *testing.T) {
expected := map[string]interface{}{
"y": []interface{}{
[]interface{}{
nil,
map[string]interface{}{},
},
},
}