@@ -16,17 +16,18 @@ import (
16
16
// Value int
17
17
// }
18
18
//
19
- // func (u *exampleUnmarshaler) UnmarshalDynamoDBStreamsAttributeValue(av *types.AttributeValue) error {
20
- // if av.N == nil {
19
+ // func (u *ExampleUnmarshaler) UnmarshalDynamoDBStreamsAttributeValue(av types.AttributeValue) error {
20
+ // avN, ok := av.(*types.AttributeValueMemberN)
21
+ // if !ok {
21
22
// return nil
22
23
// }
23
24
//
24
- // n, err := strconv.ParseInt(*av.N , 10, 0)
25
+ // n, err := strconv.ParseInt(avN.Value , 10, 0)
25
26
// if err != nil {
26
27
// return err
27
28
// }
28
29
//
29
- // u.Value = n
30
+ // u.Value = int(n)
30
31
// return nil
31
32
// }
32
33
type Unmarshaler interface {
@@ -271,6 +272,8 @@ func (d *Decoder) decodeBool(b bool, v reflect.Value) error {
271
272
}
272
273
273
274
func (d * Decoder ) decodeBinarySet (bs [][]byte , v reflect.Value ) error {
275
+ var isArray bool
276
+
274
277
switch v .Kind () {
275
278
case reflect .Slice :
276
279
// Make room for the slice elements if needed
@@ -280,6 +283,7 @@ func (d *Decoder) decodeBinarySet(bs [][]byte, v reflect.Value) error {
280
283
}
281
284
case reflect .Array :
282
285
// Limited to capacity of existing array.
286
+ isArray = true
283
287
case reflect .Interface :
284
288
set := make ([][]byte , len (bs ))
285
289
for i , b := range bs {
@@ -294,7 +298,9 @@ func (d *Decoder) decodeBinarySet(bs [][]byte, v reflect.Value) error {
294
298
}
295
299
296
300
for i := 0 ; i < v .Cap () && i < len (bs ); i ++ {
297
- v .SetLen (i + 1 )
301
+ if ! isArray {
302
+ v .SetLen (i + 1 )
303
+ }
298
304
u , elem := indirect (v .Index (i ), false )
299
305
if u != nil {
300
306
return u .UnmarshalDynamoDBStreamsAttributeValue (& types.AttributeValueMemberBS {Value : bs })
@@ -383,6 +389,8 @@ func (d *Decoder) decodeNumberToInterface(n string) (interface{}, error) {
383
389
}
384
390
385
391
func (d * Decoder ) decodeNumberSet (ns []string , v reflect.Value ) error {
392
+ var isArray bool
393
+
386
394
switch v .Kind () {
387
395
case reflect .Slice :
388
396
// Make room for the slice elements if needed
@@ -392,6 +400,7 @@ func (d *Decoder) decodeNumberSet(ns []string, v reflect.Value) error {
392
400
}
393
401
case reflect .Array :
394
402
// Limited to capacity of existing array.
403
+ isArray = true
395
404
case reflect .Interface :
396
405
if d .options .UseNumber {
397
406
set := make ([]Number , len (ns ))
@@ -416,7 +425,9 @@ func (d *Decoder) decodeNumberSet(ns []string, v reflect.Value) error {
416
425
}
417
426
418
427
for i := 0 ; i < v .Cap () && i < len (ns ); i ++ {
419
- v .SetLen (i + 1 )
428
+ if ! isArray {
429
+ v .SetLen (i + 1 )
430
+ }
420
431
u , elem := indirect (v .Index (i ), false )
421
432
if u != nil {
422
433
return u .UnmarshalDynamoDBStreamsAttributeValue (& types.AttributeValueMemberNS {Value : ns })
@@ -430,6 +441,8 @@ func (d *Decoder) decodeNumberSet(ns []string, v reflect.Value) error {
430
441
}
431
442
432
443
func (d * Decoder ) decodeList (avList []types.AttributeValue , v reflect.Value ) error {
444
+ var isArray bool
445
+
433
446
switch v .Kind () {
434
447
case reflect .Slice :
435
448
// Make room for the slice elements if needed
@@ -439,6 +452,7 @@ func (d *Decoder) decodeList(avList []types.AttributeValue, v reflect.Value) err
439
452
}
440
453
case reflect .Array :
441
454
// Limited to capacity of existing array.
455
+ isArray = true
442
456
case reflect .Interface :
443
457
s := make ([]interface {}, len (avList ))
444
458
for i , av := range avList {
@@ -454,7 +468,9 @@ func (d *Decoder) decodeList(avList []types.AttributeValue, v reflect.Value) err
454
468
455
469
// If v is not a slice, array
456
470
for i := 0 ; i < v .Cap () && i < len (avList ); i ++ {
457
- v .SetLen (i + 1 )
471
+ if ! isArray {
472
+ v .SetLen (i + 1 )
473
+ }
458
474
if err := d .decode (avList [i ], v .Index (i ), tag {}); err != nil {
459
475
return err
460
476
}
@@ -496,11 +512,8 @@ func (d *Decoder) decodeMap(avMap map[string]types.AttributeValue, v reflect.Val
496
512
TagKey : d .options .TagKey ,
497
513
})
498
514
for k , av := range avMap {
499
- if f , ok := fieldByName (fields , k ); ok {
500
- fv := fieldByIndex (v , f .Index , func (v * reflect.Value ) bool {
501
- v .Set (reflect .New (v .Type ().Elem ()))
502
- return true // to continue the loop.
503
- })
515
+ if f , ok := fields .FieldByName (k ); ok {
516
+ fv := decoderFieldByIndex (v , f .Index )
504
517
if err := d .decode (av , fv , f .tag ); err != nil {
505
518
return err
506
519
}
@@ -549,6 +562,8 @@ func (d *Decoder) decodeString(s string, v reflect.Value, fieldTag tag) error {
549
562
}
550
563
551
564
func (d * Decoder ) decodeStringSet (ss []string , v reflect.Value ) error {
565
+ var isArray bool
566
+
552
567
switch v .Kind () {
553
568
case reflect .Slice :
554
569
// Make room for the slice elements if needed
@@ -557,6 +572,7 @@ func (d *Decoder) decodeStringSet(ss []string, v reflect.Value) error {
557
572
}
558
573
case reflect .Array :
559
574
// Limited to capacity of existing array.
575
+ isArray = true
560
576
case reflect .Interface :
561
577
set := make ([]string , len (ss ))
562
578
for i , s := range ss {
@@ -571,7 +587,9 @@ func (d *Decoder) decodeStringSet(ss []string, v reflect.Value) error {
571
587
}
572
588
573
589
for i := 0 ; i < v .Cap () && i < len (ss ); i ++ {
574
- v .SetLen (i + 1 )
590
+ if ! isArray {
591
+ v .SetLen (i + 1 )
592
+ }
575
593
u , elem := indirect (v .Index (i ), false )
576
594
if u != nil {
577
595
return u .UnmarshalDynamoDBStreamsAttributeValue (& types.AttributeValueMemberSS {Value : ss })
@@ -595,6 +613,21 @@ func decodeUnixTime(n string) (time.Time, error) {
595
613
return time .Unix (v , 0 ), nil
596
614
}
597
615
616
+ // decoderFieldByIndex finds the field with the provided nested index, allocating
617
+ // embedded parent structs if needed
618
+ func decoderFieldByIndex (v reflect.Value , index []int ) reflect.Value {
619
+ for i , x := range index {
620
+ if i > 0 && v .Kind () == reflect .Ptr && v .Type ().Elem ().Kind () == reflect .Struct {
621
+ if v .IsNil () {
622
+ v .Set (reflect .New (v .Type ().Elem ()))
623
+ }
624
+ v = v .Elem ()
625
+ }
626
+ v = v .Field (x )
627
+ }
628
+ return v
629
+ }
630
+
598
631
// indirect will walk a value's interface or pointer value types. Returning
599
632
// the final value or the value a unmarshaler is defined on.
600
633
//
@@ -703,6 +736,10 @@ type UnmarshalError struct {
703
736
Type reflect.Type
704
737
}
705
738
739
+ func (e * UnmarshalError ) Unwrap () error {
740
+ return e .Err
741
+ }
742
+
706
743
// Error returns the string representation of the error satisfying the error
707
744
// interface.
708
745
func (e * UnmarshalError ) Error () string {
0 commit comments