From a2a3eeeb61661b3bac941b87c476c7fa649f122e Mon Sep 17 00:00:00 2001 From: Narek-Khachikyan <112387347+Narek-Khachikyan@users.noreply.github.com> Date: Sun, 8 Nov 2026 10:27:28 +0400 Subject: [PATCH] struct: preserve embedded values in non-unique sections --- struct.go | 3 +++ struct_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/struct.go b/struct.go index 819a6e5..037f12f 100644 --- a/struct.go +++ b/struct.go @@ -620,6 +620,9 @@ func (s *Section) reflectFrom(val reflect.Value) error { if err != nil { // Note: fieldName can never be empty here, ignore error. sec, _ = s.f.NewSection(fieldName) + } else if sec.name == s.name { + // Keep fields in the current occurrence of a non-unique section. + sec = s } // Add comment from comment tag diff --git a/struct_test.go b/struct_test.go index ad6ad04..a9bf75a 100644 --- a/struct_test.go +++ b/struct_test.go @@ -628,6 +628,39 @@ name = name } func Test_ReflectFromStructNonUniqueSections(t *testing.T) { + t.Run("reflect embedded structs into their own non unique sections", func(t *testing.T) { + type BaseSlot struct { + Id int `ini:",nonunique"` + } + type BigSlot struct { + *BaseSlot `ini:"big_slot,nonunique"` + Color string + } + type IniFile struct { + BigSlots []BigSlot `ini:"big_slot,nonunique"` + } + + cfg := Empty(LoadOptions{AllowNonUniqueSections: true}) + require.NoError(t, ReflectFrom(cfg, &IniFile{ + BigSlots: []BigSlot{ + {BaseSlot: &BaseSlot{Id: 3}, Color: "blue"}, + {BaseSlot: &BaseSlot{Id: 4}, Color: "red"}, + }, + })) + + var buf bytes.Buffer + _, err := cfg.WriteTo(&buf) + require.NoError(t, err) + assert.Equal(t, `[big_slot] +Id = 3 +Color = blue + +[big_slot] +Id = 4 +Color = red +`, buf.String()) + }) + t.Run("reflect from struct with non unique sections", func(t *testing.T) { nonUnique := &testNonUniqueSectionsStruct{ Interface: testInterface{