fix(encode): emit one key when two fields resolve to one name

Assisted-by: GLM 5.3
This commit is contained in:
2026-09-17 23:08:42 +02:00
parent aaea68efc9
commit 30b28fe7fc
4 changed files with 69 additions and 1 deletions
+36
View File
@@ -383,6 +383,42 @@ func TestMarshalerErrorPropagates(t *testing.T) {
}
}
// Two fields that resolve to one TOML key must marshal as one key, resolved
// the way the decoder resolves it, or the output would carry a duplicate key
// and never re-parse.
func TestMarshalDuplicateKeyResolvesToOneField(t *testing.T) {
type SameLevel struct {
First int `toml:"v"`
Second string `toml:"v"`
}
out, err := Marshal(SameLevel{First: 1, Second: "s"})
if err != nil {
t.Fatalf("marshal: %v", err)
}
if want := "v = \"s\"\n"; string(out) != want {
t.Errorf("output mismatch:\ngot: %q\nwant: %q", out, want)
}
type Base struct {
Name string `toml:"name"`
}
type Embedded struct {
Base
Name string `toml:"name"`
}
out, err = Marshal(Embedded{Base: Base{Name: "inner"}, Name: "outer"})
if err != nil {
t.Fatalf("marshal: %v", err)
}
// The shallower field wins, matching the decoder.
if want := "name = \"outer\"\n"; string(out) != want {
t.Errorf("output mismatch:\ngot: %q\nwant: %q", out, want)
}
if _, err := Parse(out); err != nil {
t.Errorf("re-parse: %v\ndoc:\n%s", err, out)
}
}
func TestMarshalEmbeddedScalarStruct(t *testing.T) {
// A field declared directly as a scalar-struct type (here LocalDateTime)
// must be encoded as a TOML scalar at the parent level, not rendered as