@@ -25,14 +25,28 @@ const (
25
25
OptionsMergedFull
26
26
)
27
27
28
- // ShallowMerge sets dst to the value of src, if src is non-zero and dst is zero-valued or overwrite=true.
28
+ // ShallowMerge sets dst to the value of src, if src is non-zero and dst is zero-valued
29
29
// It returns a boolean indicating whether src overwrote dst.
30
- func ShallowMerge (dst , src reflect.Value , overwrite bool ) bool {
30
+ func ShallowMerge (dst , src reflect.Value ) bool {
31
31
if ! src .IsValid () {
32
32
return false
33
33
}
34
34
35
- if dst .CanSet () && ! isEmptyValue (src ) && (overwrite || isEmptyValue (dst )) {
35
+ if dst .CanSet () && ! isEmptyValue (src ) && isEmptyValue (dst ) {
36
+ dst .Set (src )
37
+ return true
38
+ }
39
+
40
+ return false
41
+ }
42
+
43
+ // maySetValue sets dst to the value of src if:
44
+ // - src is set (has a non-nil value) and
45
+ // - dst is nil or overwrite is true
46
+ //
47
+ // It returns a boolean indicating whether src overwrote dst.
48
+ func maySetValue (dst , src reflect.Value , overwrite bool ) bool {
49
+ if src .CanSet () && ! src .IsNil () && dst .CanSet () && (overwrite || dst .IsNil ()) {
36
50
dst .Set (src )
37
51
return true
38
52
}
@@ -84,7 +98,7 @@ func ShallowMergeRouteOptions(dst, src *v1.RouteOptions) (*v1.RouteOptions, bool
84
98
overwrote := false
85
99
for i := range dstValue .NumField () {
86
100
dstField , srcField := dstValue .Field (i ), srcValue .Field (i )
87
- if srcOverride := ShallowMerge (dstField , srcField , false ); srcOverride {
101
+ if srcOverride := ShallowMerge (dstField , srcField ); srcOverride {
88
102
overwrote = true
89
103
}
90
104
}
@@ -110,7 +124,7 @@ func ShallowMergeVirtualHostOptions(dst, src *v1.VirtualHostOptions) (*v1.Virtua
110
124
overwrote := false
111
125
for i := range dstValue .NumField () {
112
126
dstField , srcField := dstValue .Field (i ), srcValue .Field (i )
113
- if srcOverride := ShallowMerge (dstField , srcField , false ); srcOverride {
127
+ if srcOverride := ShallowMerge (dstField , srcField ); srcOverride {
114
128
overwrote = true
115
129
}
116
130
}
@@ -147,23 +161,25 @@ func MergeRouteOptionsWithOverrides(dst, src *v1.RouteOptions, allowedOverrides
147
161
var dstFieldsOverwritten int
148
162
for i := range dstValue .NumField () {
149
163
dstField , srcField := dstValue .Field (i ), srcValue .Field (i )
164
+
165
+ // NOTE: important to pre-compute this because dstFieldsOverwritten must be
166
+ // incremented based on the original value of dstField and not the overwritten value
167
+ dstIsSet := dstField .CanSet () && ! dstField .IsNil ()
168
+ if dstIsSet {
169
+ dstFieldsSet ++
170
+ }
171
+
150
172
// Allow overrides if the field in dst is unset as merging from src into dst by default
151
173
// allows src to augment dst by setting fields unset in dst, hence the override check only
152
- // applies when the field in dst is set: !isEmptyValue(dstField ).
153
- if ! isEmptyValue ( dstField ) && overwriteByDefault && ! (allowedOverrides .Has (wildcardField ) ||
174
+ // applies when the field in dst is set (dstIsSet=true ).
175
+ if dstIsSet && overwriteByDefault && ! (allowedOverrides .Has (wildcardField ) ||
154
176
allowedOverrides .Has (strings .ToLower (dstValue .Type ().Field (i ).Name ))) {
155
177
continue
156
178
}
157
- // NOTE: important to pre-compute this for use in the conditional below
158
- // because dstFieldsOverwritten needs to be incremented based on the original value of dstField
159
- // and not the state of the field after the merge
160
- dstOverridable := dstField .CanSet () && ! isEmptyValue (dstField )
161
- if dstOverridable {
162
- dstFieldsSet ++
163
- }
164
- if srcOverride := ShallowMerge (dstField , srcField , overwriteByDefault ); srcOverride {
179
+
180
+ if srcOverride := maySetValue (dstField , srcField , overwriteByDefault ); srcOverride {
165
181
srcFieldsUsed ++
166
- if dstOverridable {
182
+ if dstIsSet {
167
183
dstFieldsOverwritten ++
168
184
}
169
185
}
0 commit comments