@@ -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,11 +189,11 @@ 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
199
if ct != nil && ct .hasTag {
@@ -209,52 +206,9 @@ func (t *Transformer) setByField(ctx context.Context, orig reflect.Value, cf *cF
209
206
210
207
switch kind {
211
208
case reflect .Slice , reflect .Array :
212
- reusableCF := & cField {}
213
-
214
- for i := 0 ; i < current .Len (); i ++ {
215
- if err = t .setByField (ctx , current .Index (i ), reusableCF , ct ); err != nil {
216
- return
217
- }
218
- }
219
-
209
+ err = t .setByIterable (ctx , current , ct )
220
210
case reflect .Map :
221
- reusableCF := & cField {}
222
-
223
- hasKeys := ct != nil && ct .typeof == typeKeys && ct .keys != nil
224
-
225
- for _ , key := range current .MapKeys () {
226
- newVal := reflect .New (current .Type ().Elem ()).Elem ()
227
- newVal .Set (current .MapIndex (key ))
228
-
229
- if hasKeys {
230
-
231
- // remove current map key as we may be changing it
232
- // and re-add to the map afterwards
233
- current .SetMapIndex (key , reflect.Value {})
234
-
235
- newKey := reflect .New (current .Type ().Key ()).Elem ()
236
- newKey .Set (key )
237
- key = newKey
238
-
239
- // handle map key
240
- if err = t .setByField (ctx , key , reusableCF , ct .keys ); err != nil {
241
- return
242
- }
243
-
244
- // can be nil when just keys being validated
245
- if ct .next != nil {
246
- if err = t .setByField (ctx , newVal , reusableCF , ct .next ); err != nil {
247
- return
248
- }
249
- }
250
- } else {
251
- if err = t .setByField (ctx , newVal , reusableCF , ct ); err != nil {
252
- return
253
- }
254
- }
255
- current .SetMapIndex (key , newVal )
256
- }
257
-
211
+ err = t .setByMap (ctx , current , ct )
258
212
default :
259
213
err = ErrInvalidDive
260
214
}
@@ -296,13 +250,60 @@ func (t *Transformer) setByField(ctx context.Context, orig reflect.Value, cf *cF
296
250
newVal := reflect .New (typ ).Elem ()
297
251
newVal .Set (current )
298
252
299
- if err = t .setByStruct (ctx , newVal , typ , ct ); err != nil {
253
+ if err = t .setByStruct (ctx , newVal , typ ); err != nil {
300
254
return
301
255
}
302
256
orig .Set (newVal )
303
257
return
304
258
}
305
- err = t .setByStruct (ctx , current , typ , ct )
259
+ err = t .setByStruct (ctx , current , typ )
306
260
}
307
261
return
308
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
+ }
269
+ }
270
+ return
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