diff --git a/marshal.go b/marshal.go index 737cc7d..e6b4703 100644 --- a/marshal.go +++ b/marshal.go @@ -436,6 +436,7 @@ func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, er if tree, ok := val.(*Tree); ok && mtypef.Anonymous && !opts.nameFromTag && !e.promoteAnon { e.appendTree(tval, tree) } else { + val = e.wrapTomlValue(val, tval) tval.SetPathWithOptions([]string{opts.name}, SetOptions{ Comment: opts.comment, Commented: opts.commented, @@ -474,6 +475,7 @@ func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, er if err != nil { return nil, err } + val = e.wrapTomlValue(val, tval) if e.quoteMapKeys { keyStr, err := tomlValueStringRepresentation(key.String(), "", "", e.order, e.arraysOneElementPerLine) if err != nil { @@ -516,7 +518,6 @@ func (e *Encoder) valueToOtherSlice(mtype reflect.Type, mval reflect.Value) (int // Convert given marshal value to toml value func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) { - e.line++ if mtype.Kind() == reflect.Ptr { switch { case isCustomMarshaler(mtype): @@ -579,6 +580,25 @@ func (e *Encoder) appendTree(t, o *Tree) error { return nil } +// Create a toml value with the current line number as the position line +func (e *Encoder) wrapTomlValue(val interface{}, parent *Tree) interface{} { + _, isTree := val.(*Tree) + _, isTreeS := val.([]*Tree) + if isTree || isTreeS { + return val + } + + ret := &tomlValue{ + value: val, + position: Position{ + e.line, + parent.position.Col, + }, + } + e.line++ + return ret +} + // Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v. // Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for // sub-structs, and only definite types can be unmarshaled. diff --git a/marshal_test.go b/marshal_test.go index 061c490..581657a 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -14,60 +14,69 @@ import ( ) type basicMarshalTestStruct struct { - String string `toml:"Zstring"` - StringList []string `toml:"Ystrlist"` - Sub basicMarshalTestSubStruct `toml:"Xsubdoc"` - SubList []basicMarshalTestSubStruct `toml:"Wsublist"` + String string `toml:"Zstring"` + StringList []string `toml:"Ystrlist"` + BasicMarshalTestSubAnonymousStruct + Sub basicMarshalTestSubStruct `toml:"Xsubdoc"` + SubList []basicMarshalTestSubStruct `toml:"Wsublist"` } type basicMarshalTestSubStruct struct { String2 string } -var basicTestData = basicMarshalTestStruct{ - String: "Hello", - StringList: []string{"Howdy", "Hey There"}, - Sub: basicMarshalTestSubStruct{"One"}, - SubList: []basicMarshalTestSubStruct{{"Two"}, {"Three"}}, +type BasicMarshalTestSubAnonymousStruct struct { + String3 string } -var basicTestToml = []byte(`Ystrlist = ["Howdy", "Hey There"] -Zstring = "Hello" +var basicTestData = basicMarshalTestStruct{ + String: "Hello", + StringList: []string{"Howdy", "Hey There"}, + BasicMarshalTestSubAnonymousStruct: BasicMarshalTestSubAnonymousStruct{"One"}, + Sub: basicMarshalTestSubStruct{"Two"}, + SubList: []basicMarshalTestSubStruct{{"Three"}, {"Four"}}, +} -[[Wsublist]] - String2 = "Two" +var basicTestToml = []byte(`String3 = "One" +Ystrlist = ["Howdy", "Hey There"] +Zstring = "Hello" [[Wsublist]] String2 = "Three" +[[Wsublist]] + String2 = "Four" + [Xsubdoc] - String2 = "One" + String2 = "Two" `) -var basicTestTomlCustomIndentation = []byte(`Ystrlist = ["Howdy", "Hey There"] +var basicTestTomlCustomIndentation = []byte(`String3 = "One" +Ystrlist = ["Howdy", "Hey There"] Zstring = "Hello" -[[Wsublist]] - String2 = "Two" - [[Wsublist]] String2 = "Three" +[[Wsublist]] + String2 = "Four" + [Xsubdoc] - String2 = "One" + String2 = "Two" `) var basicTestTomlOrdered = []byte(`Zstring = "Hello" Ystrlist = ["Howdy", "Hey There"] +String3 = "One" [Xsubdoc] - String2 = "One" - -[[Wsublist]] String2 = "Two" [[Wsublist]] String2 = "Three" + +[[Wsublist]] + String2 = "Four" `) var marshalTestToml = []byte(`title = "TOML Marshal Testing" diff --git a/toml.go b/toml.go index 2b138d1..4c6106c 100644 --- a/toml.go +++ b/toml.go @@ -315,6 +315,8 @@ func (t *Tree) SetPathWithOptions(keys []string, opts SetOptions, value interfac toInsert = value case *tomlValue: v.comment = opts.Comment + v.commented = opts.Commented + v.multiline = opts.Multiline toInsert = v default: toInsert = &tomlValue{value: value,