@@ -33,7 +33,7 @@ func RetryWithContext(ctx context.Context, fn func() error, attempts int, delay
3333 var err error
3434 timer := time .NewTimer (0 )
3535 defer timer .Stop ()
36- for r := 0 ; r < attempts ; r ++ {
36+ for r := range attempts {
3737 select {
3838 case <- ctx .Done ():
3939 return ctx .Err ()
@@ -92,17 +92,13 @@ func TransformAndMergeMap[T any](m1, m2 map[string]T, transform func(string) str
9292}
9393
9494// MergeMapRecursive recursively (nestedly) merges map m2 with m1 overwriting common values with m2's values.
95- func MergeMapRecursive (m1 , m2 map [string ]interface {}) (r map [string ]interface {}) {
96- r = map [string ]interface {}{}
97-
98- for key , value := range m1 {
99- r [key ] = value
100- }
95+ func MergeMapRecursive (m1 , m2 map [string ]any ) (r map [string ]any ) {
96+ r = maps .Clone (m1 )
10197
10298 for key , value := range m2 {
103- if value , ok := value .(map [string ]interface {} ); ok {
99+ if value , ok := value .(map [string ]any ); ok {
104100 if nestedValue , ok := r [key ]; ok {
105- if nestedValue , ok := nestedValue .(map [string ]interface {} ); ok {
101+ if nestedValue , ok := nestedValue .(map [string ]any ); ok {
106102 r [key ] = MergeMapRecursive (nestedValue , value )
107103 continue
108104 }
@@ -140,31 +136,42 @@ func IsNotZeroAndNotEqual[T any](given T, equal T) bool {
140136 return true
141137 }
142138
143- for i := 0 ; i < givenValue .NumField (); i ++ {
139+ for i := range givenValue .NumField () {
144140 if ! givenValue .Field (i ).IsZero () &&
145141 givenValue .Field (i ).CanInterface () &&
146142 givenValue .Field (i ).Interface () != equalValue .Field (i ).Interface () {
147-
148143 return true
149144 }
150145 }
151146 return false
152147}
153148
154149// MergeNonZero is used to merge non-zero overrides from one struct into another of the same type
155- func MergeNonZero [T any ](original T , overrides T ) T {
156- originalValue := reflect . ValueOf ( & original )
157- overridesValue := reflect . ValueOf ( & overrides )
150+ func MergeNonZero [T any ](original , overrides T ) T {
151+ // Create a copy of original that we'll modify
152+ result := original
158153
159- for i := 0 ; i < originalValue . Elem (). NumField (); i ++ {
160- if ! overridesValue . Elem (). Field ( i ). IsZero () &&
161- overridesValue . Elem (). Field ( i ). CanSet () {
154+ // Get reflect values, using the actual values not pointers to them
155+ resultValue := reflect . ValueOf ( & result ). Elem ()
156+ overridesValue := reflect . ValueOf ( overrides )
162157
163- overrideField := overridesValue .Elem ().Field (i )
164- originalValue .Elem ().Field (i ).Set (overrideField )
158+ // Ensure we're working with structs
159+ if resultValue .Kind () != reflect .Struct || overridesValue .Kind () != reflect .Struct {
160+ return original // Can't merge non-structs
161+ }
162+
163+ // Iterate through fields
164+ for i := range resultValue .NumField () {
165+ resultField := resultValue .Field (i )
166+ overrideField := overridesValue .Field (i )
167+
168+ // Check if override field is non-zero and result field can be set
169+ if ! overrideField .IsZero () && resultField .CanSet () {
170+ resultField .Set (overrideField )
165171 }
166172 }
167- return originalValue .Elem ().Interface ().(T )
173+
174+ return result
168175}
169176
170177// MergePathAndValueIntoMap takes a path in dot notation as a string and a value (also as a string for simplicity),
0 commit comments