@@ -10,7 +10,6 @@ import (
10
10
11
11
var (
12
12
timeType = reflect .TypeOf (time.Time {})
13
- defaultCField = & cField {}
14
13
restrictedAliasErr = "Alias '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
15
14
restrictedTagErr = "Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
16
15
)
@@ -76,7 +75,6 @@ func (t *Transformer) Register(tag string, fn Func) {
76
75
if ok || strings .ContainsAny (tag , restrictedTagChars ) {
77
76
panic (fmt .Sprintf (restrictedTagErr , tag ))
78
77
}
79
-
80
78
t .transformations [tag ] = fn
81
79
}
82
80
@@ -132,11 +130,10 @@ func (t *Transformer) Struct(ctx context.Context, v interface{}) error {
132
130
if val .Kind () != reflect .Struct || val .Type () == timeType {
133
131
return & ErrInvalidTransformation {typ : reflect .TypeOf (v )}
134
132
}
135
-
136
- return t .setByStruct (ctx , val , typ , nil )
133
+ return t .setByStruct (ctx , val , typ )
137
134
}
138
135
139
- func (t * Transformer ) setByStruct (ctx context.Context , current reflect.Value , typ reflect.Type , ct * cTag ) (err error ) {
136
+ func (t * Transformer ) setByStruct (ctx context.Context , current reflect.Value , typ reflect.Type ) (err error ) {
140
137
cs , ok := t .cCache .Get (typ )
141
138
if ! ok {
142
139
if cs , err = t .extractStructCache (current ); err != nil {
@@ -155,7 +152,7 @@ func (t *Transformer) setByStruct(ctx context.Context, current reflect.Value, ty
155
152
156
153
for i := 0 ; i < len (cs .fields ); i ++ {
157
154
f = cs .fields [i ]
158
- if err = t .setByField (ctx , current .Field (f .idx ), f , f .cTags ); err != nil {
155
+ if err = t .setByField (ctx , current .Field (f .idx ), f .cTags ); err != nil {
159
156
return
160
157
}
161
158
}
@@ -192,19 +189,15 @@ func (t *Transformer) Field(ctx context.Context, v interface{}, tags string) (er
192
189
}
193
190
t .tCache .lock .Unlock ()
194
191
}
195
- err = t .setByField (ctx , val , defaultCField , ctag )
192
+ err = t .setByField (ctx , val , ctag )
196
193
return
197
194
}
198
195
199
- func (t * Transformer ) setByField (ctx context.Context , orig reflect.Value , cf * cField , ct * cTag ) (err error ) {
196
+ func (t * Transformer ) setByField (ctx context.Context , orig reflect.Value , ct * cTag ) (err error ) {
200
197
current , kind := extractType (orig )
201
198
202
- if ct .hasTag {
203
- for {
204
- if ct == nil {
205
- break
206
- }
207
-
199
+ if ct != nil && ct .hasTag {
200
+ for ct != nil {
208
201
switch ct .typeof {
209
202
case typeEndKeys :
210
203
return
@@ -213,52 +206,9 @@ func (t *Transformer) setByField(ctx context.Context, orig reflect.Value, cf *cF
213
206
214
207
switch kind {
215
208
case reflect .Slice , reflect .Array :
216
- reusableCF := & cField {}
217
-
218
- for i := 0 ; i < current .Len (); i ++ {
219
- if err = t .setByField (ctx , current .Index (i ), reusableCF , ct ); err != nil {
220
- return
221
- }
222
- }
223
-
209
+ err = t .setByIterable (ctx , current , ct )
224
210
case reflect .Map :
225
- reusableCF := & cField {}
226
-
227
- hasKeys := ct != nil && ct .typeof == typeKeys && ct .keys != nil
228
-
229
- for _ , key := range current .MapKeys () {
230
- newVal := reflect .New (current .Type ().Elem ()).Elem ()
231
- newVal .Set (current .MapIndex (key ))
232
-
233
- if hasKeys {
234
-
235
- // remove current map key as we may be changing it
236
- // and re-add to the map afterwards
237
- current .SetMapIndex (key , reflect.Value {})
238
-
239
- newKey := reflect .New (current .Type ().Key ()).Elem ()
240
- newKey .Set (key )
241
- key = newKey
242
-
243
- // handle map key
244
- if err = t .setByField (ctx , key , reusableCF , ct .keys ); err != nil {
245
- return
246
- }
247
-
248
- // can be nil when just keys being validated
249
- if ct .next != nil {
250
- if err = t .setByField (ctx , newVal , reusableCF , ct .next ); err != nil {
251
- return
252
- }
253
- }
254
- } else {
255
- if err = t .setByField (ctx , newVal , reusableCF , ct ); err != nil {
256
- return
257
- }
258
- }
259
- current .SetMapIndex (key , newVal )
260
- }
261
-
211
+ err = t .setByMap (ctx , current , ct )
262
212
default :
263
213
err = ErrInvalidDive
264
214
}
@@ -300,13 +250,60 @@ func (t *Transformer) setByField(ctx context.Context, orig reflect.Value, cf *cF
300
250
newVal := reflect .New (typ ).Elem ()
301
251
newVal .Set (current )
302
252
303
- if err = t .setByStruct (ctx , newVal , typ , ct ); err != nil {
253
+ if err = t .setByStruct (ctx , newVal , typ ); err != nil {
304
254
return
305
255
}
306
256
orig .Set (newVal )
307
257
return
308
258
}
309
- err = t .setByStruct (ctx , current , typ , ct )
259
+ err = t .setByStruct (ctx , current , typ )
260
+ }
261
+ return
262
+ }
263
+
264
+ func (t * Transformer ) setByIterable (ctx context.Context , current reflect.Value , ct * cTag ) (err error ) {
265
+ for i := 0 ; i < current .Len (); i ++ {
266
+ if err = t .setByField (ctx , current .Index (i ), ct ); err != nil {
267
+ return
268
+ }
310
269
}
311
270
return
312
271
}
272
+
273
+ func (t * Transformer ) setByMap (ctx context.Context , current reflect.Value , ct * cTag ) error {
274
+ hasKeys := ct != nil && ct .typeof == typeKeys && ct .keys != nil
275
+
276
+ for _ , key := range current .MapKeys () {
277
+ newVal := reflect .New (current .Type ().Elem ()).Elem ()
278
+ newVal .Set (current .MapIndex (key ))
279
+
280
+ if hasKeys {
281
+ // remove current map key as we may be changing it
282
+ // and re-add to the map afterwards
283
+ current .SetMapIndex (key , reflect.Value {})
284
+
285
+ newKey := reflect .New (current .Type ().Key ()).Elem ()
286
+ newKey .Set (key )
287
+ key = newKey
288
+
289
+ // handle map key
290
+ if err := t .setByField (ctx , key , ct .keys ); err != nil {
291
+ return err
292
+ }
293
+
294
+ // can be nil when just keys being validated
295
+ if ct .next != nil {
296
+ if err := t .setByField (ctx , newVal , ct .next ); err != nil {
297
+ return err
298
+ }
299
+ }
300
+ } else {
301
+ if err := t .setByField (ctx , newVal , ct ); err != nil {
302
+ return err
303
+ }
304
+ }
305
+ current .SetMapIndex (key , newVal )
306
+ }
307
+
308
+ return nil
309
+ }
0 commit comments