@@ -80,7 +80,7 @@ func doStruct(
80
80
paramsInterface interface {} // DO NOT use `params` directly as it might be type `reflect.Value`
81
81
pointerReflectValue reflect.Value
82
82
pointerReflectKind reflect.Kind
83
- pointerElemReflectValue reflect.Value // The pointed element.
83
+ pointerElemReflectValue reflect.Value // The reflection value to struct element.
84
84
)
85
85
if v , ok := params .(reflect.Value ); ok {
86
86
paramsReflectValue = v
@@ -183,33 +183,37 @@ func doStruct(
183
183
var (
184
184
// Indicates that those values have been used and cannot be reused.
185
185
usedParamsKeyOrTagNameMap = structcache .GetUsedParamsKeyOrTagNameMapFromPool ()
186
+ cachedFieldInfo * structcache.CachedFieldInfo
187
+ paramsValue interface {}
186
188
)
187
189
defer structcache .PutUsedParamsKeyOrTagNameMapToPool (usedParamsKeyOrTagNameMap )
188
190
189
191
// Firstly, search according to custom mapping rules.
190
192
// If a possible direct assignment is found, reduce the number of subsequent map searches.
191
193
for paramKey , fieldName := range paramKeyToAttrMap {
192
- fieldInfo := cachedStructInfo .GetFieldInfo (fieldName )
193
- if fieldInfo != nil {
194
- if paramsValue , ok := paramsMap [paramKey ]; ok {
195
- fieldValue := fieldInfo .GetFieldReflectValue (pointerElemReflectValue )
196
- if err = bindVarToStructField (
197
- fieldValue ,
198
- paramsValue ,
199
- fieldInfo ,
200
- paramKeyToAttrMap ,
194
+ paramsValue , ok = paramsMap [paramKey ]
195
+ if ! ok {
196
+ continue
197
+ }
198
+ cachedFieldInfo = cachedStructInfo .GetFieldInfo (fieldName )
199
+ if cachedFieldInfo != nil {
200
+ fieldValue := cachedFieldInfo .GetFieldReflectValueFrom (pointerElemReflectValue )
201
+ if err = bindVarToStructField (
202
+ fieldValue ,
203
+ paramsValue ,
204
+ cachedFieldInfo ,
205
+ paramKeyToAttrMap ,
206
+ ); err != nil {
207
+ return err
208
+ }
209
+ if len (cachedFieldInfo .OtherSameNameFieldIndex ) > 0 {
210
+ if err = setOtherSameNameField (
211
+ cachedFieldInfo , paramsValue , pointerReflectValue , paramKeyToAttrMap ,
201
212
); err != nil {
202
213
return err
203
214
}
204
- if len (fieldInfo .OtherSameNameFieldIndex ) > 0 {
205
- if err = setOtherSameNameField (
206
- fieldInfo , paramsValue , pointerReflectValue , paramKeyToAttrMap ,
207
- ); err != nil {
208
- return err
209
- }
210
- }
211
- usedParamsKeyOrTagNameMap [paramKey ] = struct {}{}
212
215
}
216
+ usedParamsKeyOrTagNameMap [paramKey ] = struct {}{}
213
217
}
214
218
}
215
219
// Already done converting for given `paramsMap`.
@@ -228,15 +232,15 @@ func doStruct(
228
232
}
229
233
230
234
func setOtherSameNameField (
231
- fieldInfo * structcache.CachedFieldInfo ,
235
+ cachedFieldInfo * structcache.CachedFieldInfo ,
232
236
srcValue any ,
233
237
structValue reflect.Value ,
234
238
paramKeyToAttrMap map [string ]string ,
235
239
) (err error ) {
236
240
// loop the same field name of all sub attributes.
237
- for i := range fieldInfo .OtherSameNameFieldIndex {
238
- fieldValue := fieldInfo . GetOtherFieldReflectValue (structValue , i )
239
- if err = bindVarToStructField (fieldValue , srcValue , fieldInfo , paramKeyToAttrMap ); err != nil {
241
+ for i := range cachedFieldInfo .OtherSameNameFieldIndex {
242
+ fieldValue := cachedFieldInfo . GetOtherFieldReflectValueFrom (structValue , i )
243
+ if err = bindVarToStructField (fieldValue , srcValue , cachedFieldInfo , paramKeyToAttrMap ); err != nil {
240
244
return err
241
245
}
242
246
}
@@ -251,36 +255,36 @@ func bindStructWithLoopParamsMap(
251
255
cachedStructInfo * structcache.CachedStructInfo ,
252
256
) (err error ) {
253
257
var (
254
- fieldName string
255
- fieldInfo * structcache.CachedFieldInfo
256
- fuzzLastKey string
257
- fieldValue reflect.Value
258
- paramKey string
259
- paramValue any
260
- ok bool
258
+ fieldName string
259
+ cachedFieldInfo * structcache.CachedFieldInfo
260
+ fuzzLastKey string
261
+ fieldValue reflect.Value
262
+ paramKey string
263
+ paramValue any
264
+ ok bool
261
265
)
262
266
for paramKey , paramValue = range paramsMap {
263
267
if _ , ok = usedParamsKeyOrTagNameMap [paramKey ]; ok {
264
268
continue
265
269
}
266
- fieldInfo = cachedStructInfo .GetFieldInfo (paramKey )
267
- if fieldInfo != nil {
268
- fieldName = fieldInfo .FieldName ()
270
+ cachedFieldInfo = cachedStructInfo .GetFieldInfo (paramKey )
271
+ if cachedFieldInfo != nil {
272
+ fieldName = cachedFieldInfo .FieldName ()
269
273
// already converted using its field name?
270
274
// the field name has the more priority than tag name.
271
275
_ , ok = usedParamsKeyOrTagNameMap [fieldName ]
272
- if ok && fieldInfo .IsField {
276
+ if ok && cachedFieldInfo .IsField {
273
277
continue
274
278
}
275
- fieldValue = fieldInfo . GetFieldReflectValue (structValue )
279
+ fieldValue = cachedFieldInfo . GetFieldReflectValueFrom (structValue )
276
280
if err = bindVarToStructField (
277
- fieldValue , paramValue , fieldInfo , paramKeyToAttrMap ,
281
+ fieldValue , paramValue , cachedFieldInfo , paramKeyToAttrMap ,
278
282
); err != nil {
279
283
return err
280
284
}
281
285
// handle same field name in nested struct.
282
- if len (fieldInfo .OtherSameNameFieldIndex ) > 0 {
283
- if err = setOtherSameNameField (fieldInfo , paramValue , structValue , paramKeyToAttrMap ); err != nil {
286
+ if len (cachedFieldInfo .OtherSameNameFieldIndex ) > 0 {
287
+ if err = setOtherSameNameField (cachedFieldInfo , paramValue , structValue , paramKeyToAttrMap ); err != nil {
284
288
return err
285
289
}
286
290
}
@@ -289,40 +293,40 @@ func bindStructWithLoopParamsMap(
289
293
}
290
294
291
295
// fuzzy matching.
292
- for _ , fieldInfo = range cachedStructInfo .FieldConvertInfos {
293
- fieldName = fieldInfo .FieldName ()
296
+ for _ , cachedFieldInfo = range cachedStructInfo .FieldConvertInfos {
297
+ fieldName = cachedFieldInfo .FieldName ()
294
298
if _ , ok = usedParamsKeyOrTagNameMap [fieldName ]; ok {
295
299
continue
296
300
}
297
- fuzzLastKey = fieldInfo .LastFuzzyKey .Load ().(string )
301
+ fuzzLastKey = cachedFieldInfo .LastFuzzyKey .Load ().(string )
298
302
paramValue , ok = paramsMap [fuzzLastKey ]
299
303
if ! ok {
300
304
if strings .EqualFold (
301
- fieldInfo .RemoveSymbolsFieldName , utils .RemoveSymbols (paramKey ),
305
+ cachedFieldInfo .RemoveSymbolsFieldName , utils .RemoveSymbols (paramKey ),
302
306
) {
303
307
paramValue , ok = paramsMap [paramKey ]
304
308
// If it is found this time, update it based on what was not found last time.
305
- fieldInfo .LastFuzzyKey .Store (paramKey )
309
+ cachedFieldInfo .LastFuzzyKey .Store (paramKey )
306
310
}
307
311
}
308
312
if ok {
309
- fieldValue = fieldInfo . GetFieldReflectValue (structValue )
313
+ fieldValue = cachedFieldInfo . GetFieldReflectValueFrom (structValue )
310
314
if paramValue != nil {
311
315
if err = bindVarToStructField (
312
- fieldValue , paramValue , fieldInfo , paramKeyToAttrMap ,
316
+ fieldValue , paramValue , cachedFieldInfo , paramKeyToAttrMap ,
313
317
); err != nil {
314
318
return err
315
319
}
316
320
// handle same field name in nested struct.
317
- if len (fieldInfo .OtherSameNameFieldIndex ) > 0 {
321
+ if len (cachedFieldInfo .OtherSameNameFieldIndex ) > 0 {
318
322
if err = setOtherSameNameField (
319
- fieldInfo , paramValue , structValue , paramKeyToAttrMap ,
323
+ cachedFieldInfo , paramValue , structValue , paramKeyToAttrMap ,
320
324
); err != nil {
321
325
return err
322
326
}
323
327
}
324
328
}
325
- usedParamsKeyOrTagNameMap [fieldInfo .FieldName ()] = struct {}{}
329
+ usedParamsKeyOrTagNameMap [cachedFieldInfo .FieldName ()] = struct {}{}
326
330
break
327
331
}
328
332
}
@@ -338,33 +342,33 @@ func bindStructWithLoopFieldInfos(
338
342
cachedStructInfo * structcache.CachedStructInfo ,
339
343
) (err error ) {
340
344
var (
341
- fieldInfo * structcache.CachedFieldInfo
342
- fuzzLastKey string
343
- fieldValue reflect.Value
344
- paramKey string
345
- paramValue any
346
- matched bool
347
- ok bool
345
+ cachedFieldInfo * structcache.CachedFieldInfo
346
+ fuzzLastKey string
347
+ fieldValue reflect.Value
348
+ paramKey string
349
+ paramValue any
350
+ matched bool
351
+ ok bool
348
352
)
349
- for _ , fieldInfo = range cachedStructInfo .FieldConvertInfos {
350
- for _ , fieldTag := range fieldInfo .PriorityTagAndFieldName {
353
+ for _ , cachedFieldInfo = range cachedStructInfo .FieldConvertInfos {
354
+ for _ , fieldTag := range cachedFieldInfo .PriorityTagAndFieldName {
351
355
if paramValue , ok = paramsMap [fieldTag ]; ! ok {
352
356
continue
353
357
}
354
358
if _ , ok = usedParamsKeyOrTagNameMap [fieldTag ]; ok {
355
359
matched = true
356
360
break
357
361
}
358
- fieldValue = fieldInfo . GetFieldReflectValue (structValue )
362
+ fieldValue = cachedFieldInfo . GetFieldReflectValueFrom (structValue )
359
363
if err = bindVarToStructField (
360
- fieldValue , paramValue , fieldInfo , paramKeyToAttrMap ,
364
+ fieldValue , paramValue , cachedFieldInfo , paramKeyToAttrMap ,
361
365
); err != nil {
362
366
return err
363
367
}
364
368
// handle same field name in nested struct.
365
- if len (fieldInfo .OtherSameNameFieldIndex ) > 0 {
369
+ if len (cachedFieldInfo .OtherSameNameFieldIndex ) > 0 {
366
370
if err = setOtherSameNameField (
367
- fieldInfo , paramValue , structValue , paramKeyToAttrMap ,
371
+ cachedFieldInfo , paramValue , structValue , paramKeyToAttrMap ,
368
372
); err != nil {
369
373
return err
370
374
}
@@ -378,26 +382,26 @@ func bindStructWithLoopFieldInfos(
378
382
continue
379
383
}
380
384
381
- fuzzLastKey = fieldInfo .LastFuzzyKey .Load ().(string )
385
+ fuzzLastKey = cachedFieldInfo .LastFuzzyKey .Load ().(string )
382
386
if paramValue , ok = paramsMap [fuzzLastKey ]; ! ok {
383
387
paramKey , paramValue = fuzzyMatchingFieldName (
384
- fieldInfo .RemoveSymbolsFieldName , paramsMap , usedParamsKeyOrTagNameMap ,
388
+ cachedFieldInfo .RemoveSymbolsFieldName , paramsMap , usedParamsKeyOrTagNameMap ,
385
389
)
386
390
ok = paramKey != ""
387
- fieldInfo .LastFuzzyKey .Store (paramKey )
391
+ cachedFieldInfo .LastFuzzyKey .Store (paramKey )
388
392
}
389
393
if ok {
390
- fieldValue = fieldInfo . GetFieldReflectValue (structValue )
394
+ fieldValue = cachedFieldInfo . GetFieldReflectValueFrom (structValue )
391
395
if paramValue != nil {
392
396
if err = bindVarToStructField (
393
- fieldValue , paramValue , fieldInfo , paramKeyToAttrMap ,
397
+ fieldValue , paramValue , cachedFieldInfo , paramKeyToAttrMap ,
394
398
); err != nil {
395
399
return err
396
400
}
397
401
// handle same field name in nested struct.
398
- if len (fieldInfo .OtherSameNameFieldIndex ) > 0 {
402
+ if len (cachedFieldInfo .OtherSameNameFieldIndex ) > 0 {
399
403
if err = setOtherSameNameField (
400
- fieldInfo , paramValue , structValue , paramKeyToAttrMap ,
404
+ cachedFieldInfo , paramValue , structValue , paramKeyToAttrMap ,
401
405
); err != nil {
402
406
return err
403
407
}
@@ -432,7 +436,7 @@ func fuzzyMatchingFieldName(
432
436
func bindVarToStructField (
433
437
fieldValue reflect.Value ,
434
438
srcValue interface {},
435
- fieldInfo * structcache.CachedFieldInfo ,
439
+ cachedFieldInfo * structcache.CachedFieldInfo ,
436
440
paramKeyToAttrMap map [string ]string ,
437
441
) (err error ) {
438
442
if ! fieldValue .IsValid () {
@@ -445,7 +449,7 @@ func bindVarToStructField(
445
449
defer func () {
446
450
if exception := recover (); exception != nil {
447
451
if err = bindVarToReflectValue (fieldValue , srcValue , paramKeyToAttrMap ); err != nil {
448
- err = gerror .Wrapf (err , `error binding srcValue to attribute "%s"` , fieldInfo .FieldName ())
452
+ err = gerror .Wrapf (err , `error binding srcValue to attribute "%s"` , cachedFieldInfo .FieldName ())
449
453
}
450
454
}
451
455
}()
@@ -460,27 +464,27 @@ func bindVarToStructField(
460
464
customConverterInput reflect.Value
461
465
ok bool
462
466
)
463
- if fieldInfo .IsCustomConvert {
467
+ if cachedFieldInfo .IsCustomConvert {
464
468
if customConverterInput , ok = srcValue .(reflect.Value ); ! ok {
465
469
customConverterInput = reflect .ValueOf (srcValue )
466
470
}
467
471
if ok , err = callCustomConverter (customConverterInput , fieldValue ); ok || err != nil {
468
472
return
469
473
}
470
474
}
471
- if fieldInfo .IsCommonInterface {
475
+ if cachedFieldInfo .IsCommonInterface {
472
476
if ok , err = bindVarToReflectValueWithInterfaceCheck (fieldValue , srcValue ); ok || err != nil {
473
477
return
474
478
}
475
479
}
476
480
// Common types use fast assignment logic
477
- if fieldInfo .ConvertFunc != nil {
478
- fieldInfo .ConvertFunc (srcValue , fieldValue )
481
+ if cachedFieldInfo .ConvertFunc != nil {
482
+ cachedFieldInfo .ConvertFunc (srcValue , fieldValue )
479
483
return nil
480
484
}
481
485
doConvertWithReflectValueSet (fieldValue , doConvertInput {
482
486
FromValue : srcValue ,
483
- ToTypeName : fieldInfo .StructField .Type .String (),
487
+ ToTypeName : cachedFieldInfo .StructField .Type .String (),
484
488
ReferValue : fieldValue ,
485
489
})
486
490
return nil
0 commit comments