From dba45d427ff48cfb9bcf633db3a8e43b7364e261 Mon Sep 17 00:00:00 2001 From: Kamil Samigullin Date: Thu, 30 May 2019 06:55:49 +0300 Subject: [PATCH] Handle anonymous structs (#281) Handle anonymous structs during Unmarshal. Fixes #279 --- marshal.go | 9 +++++++++ marshal_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/marshal.go b/marshal.go index 0e1c57e..a0a5ca1 100644 --- a/marshal.go +++ b/marshal.go @@ -604,6 +604,15 @@ func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, } mval.Field(i).Set(reflect.ValueOf(val)) } + + // save the old behavior above and try to check anonymous structs + if !found && opts.defaultValue == "" && mtypef.Anonymous && mtypef.Type.Kind() == reflect.Struct { + v, err := d.valueFromTree(mtypef.Type, tval) + if err != nil { + return v, err + } + mval.Field(i).Set(v) + } } } case reflect.Map: diff --git a/marshal_test.go b/marshal_test.go index cc23dca..02dc9fe 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -1417,3 +1417,46 @@ func TestUnmarshalDefaultFailureUnsupported(t *testing.T) { t.Fatal("should error") } } + +func TestUnmarshalNestedAnonymousStructs(t *testing.T) { + type Nested struct { + Value string `toml:"nested_field"` + } + type Deep struct { + Nested + } + type Document struct { + Deep + Value string `toml:"own_field"` + } + + var doc Document + + err := Unmarshal([]byte(`nested_field = "nested value"`+"\n"+`own_field = "own value"`), &doc) + if err != nil { + t.Fatal("should not error") + } + if doc.Value != "own value" || doc.Nested.Value != "nested value" { + t.Fatal("unexpected values") + } +} + +func TestUnmarshalNestedAnonymousStructs_Controversial(t *testing.T) { + type Nested struct { + Value string `toml:"nested"` + } + type Deep struct { + Nested + } + type Document struct { + Deep + Value string `toml:"own"` + } + + var doc Document + + err := Unmarshal([]byte(`nested = "nested value"`+"\n"+`own = "own value"`), &doc) + if err == nil { + t.Fatal("should error") + } +}