Fix unmarshaling of nested structs (#340)

Fixes #339
This commit is contained in:
Allen
2020-03-23 23:23:21 +08:00
committed by GitHub
parent a12e102214
commit 7ee1118b4b
2 changed files with 58 additions and 14 deletions
+20 -14
View File
@@ -575,20 +575,22 @@ func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.V
} }
found := false found := false
for _, key := range keysToTry { if tval != nil {
exists := tval.Has(key) for _, key := range keysToTry {
if !exists { exists := tval.Has(key)
continue if !exists {
continue
}
val := tval.Get(key)
fval := mval.Field(i)
mvalf, err := d.valueFromToml(mtypef.Type, val, &fval)
if err != nil {
return mval, formatError(err, tval.GetPosition(key))
}
mval.Field(i).Set(mvalf)
found = true
break
} }
val := tval.Get(key)
fval := mval.Field(i)
mvalf, err := d.valueFromToml(mtypef.Type, val, &fval)
if err != nil {
return mval, formatError(err, tval.GetPosition(key))
}
mval.Field(i).Set(mvalf)
found = true
break
} }
if !found && opts.defaultValue != "" { if !found && opts.defaultValue != "" {
@@ -626,7 +628,11 @@ func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.V
// save the old behavior above and try to check structs // save the old behavior above and try to check structs
if !found && opts.defaultValue == "" && mtypef.Type.Kind() == reflect.Struct { if !found && opts.defaultValue == "" && mtypef.Type.Kind() == reflect.Struct {
v, err := d.valueFromTree(mtypef.Type, tval, nil) tmpTval := tval
if !mtypef.Anonymous {
tmpTval = nil
}
v, err := d.valueFromTree(mtypef.Type, tmpTval, nil)
if err != nil { if err != nil {
return v, err return v, err
} }
+38
View File
@@ -2399,3 +2399,41 @@ func TestMarshalLocalTime(t *testing.T) {
}) })
} }
} }
// test case for issue #339
func TestUnmarshalSameInnerField(t *testing.T) {
type InterStruct2 struct {
Test string
Name string
Age int
}
type Inter2 struct {
Name string
Age int
InterStruct2 InterStruct2
}
type Server struct {
Name string `toml:"name"`
Inter2 Inter2 `toml:"inter2"`
}
var server Server
if err := Unmarshal([]byte(`name = "123"
[inter2]
name = "inter2"
age = 222`), &server); err == nil {
expected := Server{
Name: "123",
Inter2: Inter2{
Name: "inter2",
Age: 222,
},
}
if !reflect.DeepEqual(server, expected) {
t.Errorf("Bad unmarshal: expected %v, got %v", expected, server)
}
} else {
t.Fatalf("unexpected error: %v", err)
}
}