diff --git a/marshal.go b/marshal.go index ac77be1..d71255a 100644 --- a/marshal.go +++ b/marshal.go @@ -575,20 +575,22 @@ func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.V } found := false - for _, key := range keysToTry { - exists := tval.Has(key) - if !exists { - continue + if tval != nil { + for _, key := range keysToTry { + exists := tval.Has(key) + 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 != "" { @@ -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 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 { return v, err } diff --git a/marshal_test.go b/marshal_test.go index aaaa744..4168b16 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -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) + } +}