github.com/aavshr/aws-sdk-go@v1.41.3/service/dynamodb/dynamodbattribute/decode.go (about)

     1  package dynamodbattribute
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"fmt"
     7  	"reflect"
     8  	"strconv"
     9  	"time"
    10  
    11  	"github.com/aavshr/aws-sdk-go/aws"
    12  	"github.com/aavshr/aws-sdk-go/service/dynamodb"
    13  )
    14  
    15  // An Unmarshaler is an interface to provide custom unmarshaling of
    16  // AttributeValues. Use this to provide custom logic determining
    17  // how AttributeValues should be unmarshaled.
    18  // 		type ExampleUnmarshaler struct {
    19  // 			Value int
    20  // 		}
    21  //
    22  // 		func (u *ExampleUnmarshaler) UnmarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
    23  // 			if av.N == nil {
    24  // 				return nil
    25  // 			}
    26  //
    27  // 			n, err := strconv.ParseInt(*av.N, 10, 0)
    28  // 			if err != nil {
    29  // 				return err
    30  // 			}
    31  //
    32  // 			u.Value = int(n)
    33  // 			return nil
    34  // 		}
    35  type Unmarshaler interface {
    36  	UnmarshalDynamoDBAttributeValue(*dynamodb.AttributeValue) error
    37  }
    38  
    39  // Unmarshal will unmarshal DynamoDB AttributeValues to Go value types.
    40  // Both generic interface{} and concrete types are valid unmarshal
    41  // destination types.
    42  //
    43  // Unmarshal will allocate maps, slices, and pointers as needed to
    44  // unmarshal the AttributeValue into the provided type value.
    45  //
    46  // When unmarshaling AttributeValues into structs Unmarshal matches
    47  // the field names of the struct to the AttributeValue Map keys.
    48  // Initially it will look for exact field name matching, but will
    49  // fall back to case insensitive if not exact match is found.
    50  //
    51  // With the exception of omitempty, omitemptyelem, binaryset, numberset
    52  // and stringset all struct tags used by Marshal are also used by
    53  // Unmarshal.
    54  //
    55  // When decoding AttributeValues to interfaces Unmarshal will use the
    56  // following types.
    57  //
    58  //		[]byte,                 AV Binary (B)
    59  //		[][]byte,               AV Binary Set (BS)
    60  //		bool,                   AV Boolean (BOOL)
    61  //		[]interface{},          AV List (L)
    62  //		map[string]interface{}, AV Map (M)
    63  //		float64,                AV Number (N)
    64  //		Number,                 AV Number (N) with UseNumber set
    65  //		[]float64,              AV Number Set (NS)
    66  //		[]Number,               AV Number Set (NS) with UseNumber set
    67  //		string,                 AV String (S)
    68  //		[]string,               AV String Set (SS)
    69  //
    70  // If the Decoder option, UseNumber is set numbers will be unmarshaled
    71  // as Number values instead of float64. Use this to maintain the original
    72  // string formating of the number as it was represented in the AttributeValue.
    73  // In addition provides additional opportunities to parse the number
    74  // string based on individual use cases.
    75  //
    76  // When unmarshaling any error that occurs will halt the unmarshal
    77  // and return the error.
    78  //
    79  // The output value provided must be a non-nil pointer
    80  func Unmarshal(av *dynamodb.AttributeValue, out interface{}) error {
    81  	return NewDecoder().Decode(av, out)
    82  }
    83  
    84  // UnmarshalMap is an alias for Unmarshal which unmarshals from
    85  // a map of AttributeValues.
    86  //
    87  // The output value provided must be a non-nil pointer
    88  func UnmarshalMap(m map[string]*dynamodb.AttributeValue, out interface{}) error {
    89  	return NewDecoder().Decode(&dynamodb.AttributeValue{M: m}, out)
    90  }
    91  
    92  // UnmarshalList is an alias for Unmarshal func which unmarshals
    93  // a slice of AttributeValues.
    94  //
    95  // The output value provided must be a non-nil pointer
    96  func UnmarshalList(l []*dynamodb.AttributeValue, out interface{}) error {
    97  	return NewDecoder().Decode(&dynamodb.AttributeValue{L: l}, out)
    98  }
    99  
   100  // UnmarshalListOfMaps is an alias for Unmarshal func which unmarshals a
   101  // slice of maps of attribute values.
   102  //
   103  // This is useful for when you need to unmarshal the Items from a DynamoDB
   104  // Query API call.
   105  //
   106  // The output value provided must be a non-nil pointer
   107  func UnmarshalListOfMaps(l []map[string]*dynamodb.AttributeValue, out interface{}) error {
   108  	items := make([]*dynamodb.AttributeValue, len(l))
   109  	for i, m := range l {
   110  		items[i] = &dynamodb.AttributeValue{M: m}
   111  	}
   112  
   113  	return UnmarshalList(items, out)
   114  }
   115  
   116  // A Decoder provides unmarshaling AttributeValues to Go value types.
   117  type Decoder struct {
   118  	MarshalOptions
   119  
   120  	// Instructs the decoder to decode AttributeValue Numbers as
   121  	// Number type instead of float64 when the destination type
   122  	// is interface{}. Similar to encoding/json.Number
   123  	UseNumber bool
   124  
   125  	// Instructs the decoder to use Json Number
   126  	UseJsonNumber bool
   127  }
   128  
   129  // NewDecoder creates a new Decoder with default configuration. Use
   130  // the `opts` functional options to override the default configuration.
   131  func NewDecoder(opts ...func(*Decoder)) *Decoder {
   132  	d := &Decoder{
   133  		MarshalOptions: MarshalOptions{
   134  			SupportJSONTags: true,
   135  		},
   136  	}
   137  	for _, o := range opts {
   138  		o(d)
   139  	}
   140  
   141  	return d
   142  }
   143  
   144  // Decode will unmarshal an AttributeValue into a Go value type. An error
   145  // will be return if the decoder is unable to unmarshal the AttributeValue
   146  // to the provide Go value type.
   147  //
   148  // The output value provided must be a non-nil pointer
   149  func (d *Decoder) Decode(av *dynamodb.AttributeValue, out interface{}, opts ...func(*Decoder)) error {
   150  	v := reflect.ValueOf(out)
   151  	if v.Kind() != reflect.Ptr || v.IsNil() || !v.IsValid() {
   152  		return &InvalidUnmarshalError{Type: reflect.TypeOf(out)}
   153  	}
   154  
   155  	return d.decode(av, v, tag{})
   156  }
   157  
   158  var stringInterfaceMapType = reflect.TypeOf(map[string]interface{}(nil))
   159  var byteSliceType = reflect.TypeOf([]byte(nil))
   160  var byteSliceSlicetype = reflect.TypeOf([][]byte(nil))
   161  var numberType = reflect.TypeOf(Number(""))
   162  var timeType = reflect.TypeOf(time.Time{})
   163  var ptrStringType = reflect.TypeOf(aws.String(""))
   164  var jsonNumberType = reflect.TypeOf(json.Number(""))
   165  
   166  func (d *Decoder) decode(av *dynamodb.AttributeValue, v reflect.Value, fieldTag tag) error {
   167  	var u Unmarshaler
   168  	if av == nil || av.NULL != nil {
   169  		u, v = indirect(v, true)
   170  		if u != nil {
   171  			return u.UnmarshalDynamoDBAttributeValue(av)
   172  		}
   173  		return d.decodeNull(v)
   174  	}
   175  
   176  	u, v = indirect(v, false)
   177  	if u != nil {
   178  		return u.UnmarshalDynamoDBAttributeValue(av)
   179  	}
   180  
   181  	switch {
   182  	case av.B != nil:
   183  		return d.decodeBinary(av.B, v)
   184  	case av.BOOL != nil:
   185  		return d.decodeBool(av.BOOL, v)
   186  	case av.BS != nil:
   187  		return d.decodeBinarySet(av.BS, v)
   188  	case av.L != nil:
   189  		return d.decodeList(av.L, v)
   190  	case av.M != nil:
   191  		return d.decodeMap(av.M, v)
   192  	case av.N != nil:
   193  		return d.decodeNumber(av.N, v, fieldTag)
   194  	case av.NS != nil:
   195  		return d.decodeNumberSet(av.NS, v)
   196  	case av.S != nil:
   197  		return d.decodeString(av.S, v, fieldTag)
   198  	case av.SS != nil:
   199  		return d.decodeStringSet(av.SS, v)
   200  	}
   201  
   202  	return nil
   203  }
   204  
   205  func (d *Decoder) decodeBinary(b []byte, v reflect.Value) error {
   206  	if v.Kind() == reflect.Interface {
   207  		buf := make([]byte, len(b))
   208  		copy(buf, b)
   209  		v.Set(reflect.ValueOf(buf))
   210  		return nil
   211  	}
   212  
   213  	if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
   214  		return &UnmarshalTypeError{Value: "binary", Type: v.Type()}
   215  	}
   216  
   217  	if v.Type() == byteSliceType {
   218  		// Optimization for []byte types
   219  		if v.IsNil() || v.Cap() < len(b) {
   220  			v.Set(reflect.MakeSlice(byteSliceType, len(b), len(b)))
   221  		} else if v.Len() != len(b) {
   222  			v.SetLen(len(b))
   223  		}
   224  		copy(v.Interface().([]byte), b)
   225  		return nil
   226  	}
   227  
   228  	switch v.Type().Elem().Kind() {
   229  	case reflect.Uint8:
   230  		// Fallback to reflection copy for type aliased of []byte type
   231  		if v.Kind() != reflect.Array && (v.IsNil() || v.Cap() < len(b)) {
   232  			v.Set(reflect.MakeSlice(v.Type(), len(b), len(b)))
   233  		} else if v.Len() != len(b) {
   234  			v.SetLen(len(b))
   235  		}
   236  		for i := 0; i < len(b); i++ {
   237  			v.Index(i).SetUint(uint64(b[i]))
   238  		}
   239  	default:
   240  		if v.Kind() == reflect.Array {
   241  			switch v.Type().Elem().Kind() {
   242  			case reflect.Uint8:
   243  				reflect.Copy(v, reflect.ValueOf(b))
   244  			default:
   245  				return &UnmarshalTypeError{Value: "binary", Type: v.Type()}
   246  			}
   247  
   248  			break
   249  		}
   250  
   251  		return &UnmarshalTypeError{Value: "binary", Type: v.Type()}
   252  	}
   253  
   254  	return nil
   255  }
   256  
   257  func (d *Decoder) decodeBool(b *bool, v reflect.Value) error {
   258  	switch v.Kind() {
   259  	case reflect.Bool, reflect.Interface:
   260  		v.Set(reflect.ValueOf(*b).Convert(v.Type()))
   261  	default:
   262  		return &UnmarshalTypeError{Value: "bool", Type: v.Type()}
   263  	}
   264  
   265  	return nil
   266  }
   267  
   268  func (d *Decoder) decodeBinarySet(bs [][]byte, v reflect.Value) error {
   269  	isArray := false
   270  
   271  	switch v.Kind() {
   272  	case reflect.Slice:
   273  		// Make room for the slice elements if needed
   274  		if v.IsNil() || v.Cap() < len(bs) {
   275  			// What about if ignoring nil/empty values?
   276  			v.Set(reflect.MakeSlice(v.Type(), 0, len(bs)))
   277  		}
   278  	case reflect.Array:
   279  		// Limited to capacity of existing array.
   280  		isArray = true
   281  	case reflect.Interface:
   282  		set := make([][]byte, len(bs))
   283  		for i, b := range bs {
   284  			if err := d.decodeBinary(b, reflect.ValueOf(&set[i]).Elem()); err != nil {
   285  				return err
   286  			}
   287  		}
   288  		v.Set(reflect.ValueOf(set))
   289  		return nil
   290  	default:
   291  		return &UnmarshalTypeError{Value: "binary set", Type: v.Type()}
   292  	}
   293  
   294  	for i := 0; i < v.Cap() && i < len(bs); i++ {
   295  		if !isArray {
   296  			v.SetLen(i + 1)
   297  		}
   298  		u, elem := indirect(v.Index(i), false)
   299  		if u != nil {
   300  			return u.UnmarshalDynamoDBAttributeValue(&dynamodb.AttributeValue{BS: bs})
   301  		}
   302  		if err := d.decodeBinary(bs[i], elem); err != nil {
   303  			return err
   304  		}
   305  	}
   306  
   307  	return nil
   308  }
   309  
   310  func (d *Decoder) decodeNumber(n *string, v reflect.Value, fieldTag tag) error {
   311  	switch v.Kind() {
   312  	case reflect.Interface:
   313  		i, err := d.decodeNumberToInterface(n)
   314  		if err != nil {
   315  			return err
   316  		}
   317  		v.Set(reflect.ValueOf(i))
   318  		return nil
   319  	case reflect.String:
   320  		if v.Type() == numberType { // Support Number value type
   321  			v.Set(reflect.ValueOf(Number(*n)))
   322  			return nil
   323  		}
   324  		v.SetString(*n)
   325  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   326  		i, err := strconv.ParseInt(*n, 10, 64)
   327  		if err != nil {
   328  			return err
   329  		}
   330  		if v.OverflowInt(i) {
   331  			return &UnmarshalTypeError{
   332  				Value: fmt.Sprintf("number overflow, %s", *n),
   333  				Type:  v.Type(),
   334  			}
   335  		}
   336  		v.SetInt(i)
   337  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   338  		i, err := strconv.ParseUint(*n, 10, 64)
   339  		if err != nil {
   340  			return err
   341  		}
   342  		if v.OverflowUint(i) {
   343  			return &UnmarshalTypeError{
   344  				Value: fmt.Sprintf("number overflow, %s", *n),
   345  				Type:  v.Type(),
   346  			}
   347  		}
   348  		v.SetUint(i)
   349  	case reflect.Float32, reflect.Float64:
   350  		i, err := strconv.ParseFloat(*n, 64)
   351  		if err != nil {
   352  			return err
   353  		}
   354  		if v.OverflowFloat(i) {
   355  			return &UnmarshalTypeError{
   356  				Value: fmt.Sprintf("number overflow, %s", *n),
   357  				Type:  v.Type(),
   358  			}
   359  		}
   360  		v.SetFloat(i)
   361  	default:
   362  		if v.Type().ConvertibleTo(timeType) && fieldTag.AsUnixTime {
   363  			t, err := decodeUnixTime(*n)
   364  			if err != nil {
   365  				return err
   366  			}
   367  			v.Set(reflect.ValueOf(t).Convert(v.Type()))
   368  			return nil
   369  		}
   370  		return &UnmarshalTypeError{Value: "number", Type: v.Type()}
   371  	}
   372  
   373  	return nil
   374  }
   375  
   376  func (d *Decoder) decodeNumberToInterface(n *string) (interface{}, error) {
   377  	if d.UseJsonNumber {
   378  		return json.Number(*n), nil
   379  	}
   380  
   381  	if d.UseNumber {
   382  		return Number(*n), nil
   383  	}
   384  
   385  	// Default to float64 for all numbers
   386  	return strconv.ParseFloat(*n, 64)
   387  }
   388  
   389  func (d *Decoder) decodeNumberSet(ns []*string, v reflect.Value) error {
   390  	isArray := false
   391  
   392  	switch v.Kind() {
   393  	case reflect.Slice:
   394  		// Make room for the slice elements if needed
   395  		if v.IsNil() || v.Cap() < len(ns) {
   396  			// What about if ignoring nil/empty values?
   397  			v.Set(reflect.MakeSlice(v.Type(), 0, len(ns)))
   398  		}
   399  	case reflect.Array:
   400  		// Limited to capacity of existing array.
   401  		isArray = true
   402  	case reflect.Interface:
   403  		if d.UseNumber {
   404  			set := make([]Number, len(ns))
   405  			for i, n := range ns {
   406  				if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem(), tag{}); err != nil {
   407  					return err
   408  				}
   409  			}
   410  			v.Set(reflect.ValueOf(set))
   411  		} else {
   412  			set := make([]float64, len(ns))
   413  			for i, n := range ns {
   414  				if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem(), tag{}); err != nil {
   415  					return err
   416  				}
   417  			}
   418  			v.Set(reflect.ValueOf(set))
   419  		}
   420  		return nil
   421  	default:
   422  		return &UnmarshalTypeError{Value: "number set", Type: v.Type()}
   423  	}
   424  
   425  	for i := 0; i < v.Cap() && i < len(ns); i++ {
   426  		if !isArray {
   427  			v.SetLen(i + 1)
   428  		}
   429  		u, elem := indirect(v.Index(i), false)
   430  		if u != nil {
   431  			return u.UnmarshalDynamoDBAttributeValue(&dynamodb.AttributeValue{NS: ns})
   432  		}
   433  		if err := d.decodeNumber(ns[i], elem, tag{}); err != nil {
   434  			return err
   435  		}
   436  	}
   437  
   438  	return nil
   439  }
   440  
   441  func (d *Decoder) decodeList(avList []*dynamodb.AttributeValue, v reflect.Value) error {
   442  	isArray := false
   443  
   444  	switch v.Kind() {
   445  	case reflect.Slice:
   446  		// Make room for the slice elements if needed
   447  		if v.IsNil() || v.Cap() < len(avList) {
   448  			// What about if ignoring nil/empty values?
   449  			v.Set(reflect.MakeSlice(v.Type(), 0, len(avList)))
   450  		}
   451  	case reflect.Array:
   452  		// Limited to capacity of existing array.
   453  		isArray = true
   454  	case reflect.Interface:
   455  		s := make([]interface{}, len(avList))
   456  		for i, av := range avList {
   457  			if err := d.decode(av, reflect.ValueOf(&s[i]).Elem(), tag{}); err != nil {
   458  				return err
   459  			}
   460  		}
   461  		v.Set(reflect.ValueOf(s))
   462  		return nil
   463  	default:
   464  		return &UnmarshalTypeError{Value: "list", Type: v.Type()}
   465  	}
   466  
   467  	// If v is not a slice, array
   468  	for i := 0; i < v.Cap() && i < len(avList); i++ {
   469  		if !isArray {
   470  			v.SetLen(i + 1)
   471  		}
   472  
   473  		if err := d.decode(avList[i], v.Index(i), tag{}); err != nil {
   474  			return err
   475  		}
   476  	}
   477  
   478  	return nil
   479  }
   480  
   481  func (d *Decoder) decodeMap(avMap map[string]*dynamodb.AttributeValue, v reflect.Value) error {
   482  	switch v.Kind() {
   483  	case reflect.Map:
   484  		t := v.Type()
   485  		if t.Key().Kind() != reflect.String {
   486  			return &UnmarshalTypeError{Value: "map string key", Type: t.Key()}
   487  		}
   488  		if v.IsNil() {
   489  			v.Set(reflect.MakeMap(t))
   490  		}
   491  	case reflect.Struct:
   492  	case reflect.Interface:
   493  		v.Set(reflect.MakeMap(stringInterfaceMapType))
   494  		v = v.Elem()
   495  	default:
   496  		return &UnmarshalTypeError{Value: "map", Type: v.Type()}
   497  	}
   498  
   499  	if v.Kind() == reflect.Map {
   500  		for k, av := range avMap {
   501  			key := reflect.New(v.Type().Key()).Elem()
   502  			key.SetString(k)
   503  			elem := reflect.New(v.Type().Elem()).Elem()
   504  			if err := d.decode(av, elem, tag{}); err != nil {
   505  				return err
   506  			}
   507  			v.SetMapIndex(key, elem)
   508  		}
   509  	} else if v.Kind() == reflect.Struct {
   510  		fields := unionStructFields(v.Type(), d.MarshalOptions)
   511  		for k, av := range avMap {
   512  			if f, ok := fields.FieldByName(k); ok {
   513  				fv := decoderFieldByIndex(v, f.Index)
   514  				if err := d.decode(av, fv, f.tag); err != nil {
   515  					return err
   516  				}
   517  			}
   518  		}
   519  	}
   520  
   521  	return nil
   522  }
   523  
   524  func (d *Decoder) decodeNull(v reflect.Value) error {
   525  	if v.IsValid() && v.CanSet() {
   526  		v.Set(reflect.Zero(v.Type()))
   527  	}
   528  
   529  	return nil
   530  }
   531  
   532  func (d *Decoder) decodeString(s *string, v reflect.Value, fieldTag tag) error {
   533  	if fieldTag.AsString {
   534  		return d.decodeNumber(s, v, fieldTag)
   535  	}
   536  
   537  	// To maintain backwards compatibility with ConvertFrom family of methods which
   538  	// converted strings to time.Time structs
   539  	if v.Type().ConvertibleTo(timeType) {
   540  		t, err := time.Parse(time.RFC3339, *s)
   541  		if err != nil {
   542  			return err
   543  		}
   544  		v.Set(reflect.ValueOf(t).Convert(v.Type()))
   545  		return nil
   546  	}
   547  
   548  	switch v.Kind() {
   549  	case reflect.String:
   550  		v.SetString(*s)
   551  	case reflect.Slice:
   552  		// To maintain backwards compatibility with the ConvertFrom family of methods
   553  		// which converted []byte into base64-encoded strings if the input was typed
   554  		if v.Type() == byteSliceType {
   555  			decoded, err := base64.StdEncoding.DecodeString(*s)
   556  			if err != nil {
   557  				return &UnmarshalError{Err: err, Value: "string", Type: v.Type()}
   558  			}
   559  			v.SetBytes(decoded)
   560  		}
   561  	case reflect.Interface:
   562  		// Ensure type aliasing is handled properly
   563  		v.Set(reflect.ValueOf(*s).Convert(v.Type()))
   564  	default:
   565  		return &UnmarshalTypeError{Value: "string", Type: v.Type()}
   566  	}
   567  
   568  	return nil
   569  }
   570  
   571  func (d *Decoder) decodeStringSet(ss []*string, v reflect.Value) error {
   572  	isArray := false
   573  
   574  	switch v.Kind() {
   575  	case reflect.Slice:
   576  		// Make room for the slice elements if needed
   577  		if v.IsNil() || v.Cap() < len(ss) {
   578  			v.Set(reflect.MakeSlice(v.Type(), 0, len(ss)))
   579  		}
   580  	case reflect.Array:
   581  		// Limited to capacity of existing array.
   582  		isArray = true
   583  	case reflect.Interface:
   584  		set := make([]string, len(ss))
   585  		for i, s := range ss {
   586  			if err := d.decodeString(s, reflect.ValueOf(&set[i]).Elem(), tag{}); err != nil {
   587  				return err
   588  			}
   589  		}
   590  		v.Set(reflect.ValueOf(set))
   591  		return nil
   592  	default:
   593  		return &UnmarshalTypeError{Value: "string set", Type: v.Type()}
   594  	}
   595  
   596  	for i := 0; i < v.Cap() && i < len(ss); i++ {
   597  		if !isArray {
   598  			v.SetLen(i + 1)
   599  		}
   600  		u, elem := indirect(v.Index(i), false)
   601  		if u != nil {
   602  			return u.UnmarshalDynamoDBAttributeValue(&dynamodb.AttributeValue{SS: ss})
   603  		}
   604  		if err := d.decodeString(ss[i], elem, tag{}); err != nil {
   605  			return err
   606  		}
   607  	}
   608  
   609  	return nil
   610  }
   611  
   612  func decodeUnixTime(n string) (time.Time, error) {
   613  	v, err := strconv.ParseInt(n, 10, 64)
   614  	if err != nil {
   615  		return time.Time{}, &UnmarshalError{
   616  			Err: err, Value: n, Type: timeType,
   617  		}
   618  	}
   619  
   620  	return time.Unix(v, 0), nil
   621  }
   622  
   623  // decoderFieldByIndex finds the field with the provided nested index, allocating
   624  // embedded parent structs if needed
   625  func decoderFieldByIndex(v reflect.Value, index []int) reflect.Value {
   626  	for i, x := range index {
   627  		if i > 0 && v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct {
   628  			if v.IsNil() {
   629  				v.Set(reflect.New(v.Type().Elem()))
   630  			}
   631  			v = v.Elem()
   632  		}
   633  		v = v.Field(x)
   634  	}
   635  	return v
   636  }
   637  
   638  // indirect will walk a value's interface or pointer value types. Returning
   639  // the final value or the value a unmarshaler is defined on.
   640  //
   641  // Based on the enoding/json type reflect value type indirection in Go Stdlib
   642  // https://golang.org/src/encoding/json/decode.go indirect func.
   643  func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, reflect.Value) {
   644  	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
   645  		v = v.Addr()
   646  	}
   647  	for {
   648  		if v.Kind() == reflect.Interface && !v.IsNil() {
   649  			e := v.Elem()
   650  			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
   651  				v = e
   652  				continue
   653  			}
   654  		}
   655  		if v.Kind() != reflect.Ptr {
   656  			break
   657  		}
   658  		if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
   659  			break
   660  		}
   661  		if v.IsNil() {
   662  			v.Set(reflect.New(v.Type().Elem()))
   663  		}
   664  		if v.Type().NumMethod() > 0 {
   665  			if u, ok := v.Interface().(Unmarshaler); ok {
   666  				return u, reflect.Value{}
   667  			}
   668  		}
   669  		v = v.Elem()
   670  	}
   671  
   672  	return nil, v
   673  }
   674  
   675  // A Number represents a Attributevalue number literal.
   676  type Number string
   677  
   678  // Float64 attempts to cast the number ot a float64, returning
   679  // the result of the case or error if the case failed.
   680  func (n Number) Float64() (float64, error) {
   681  	return strconv.ParseFloat(string(n), 64)
   682  }
   683  
   684  // Int64 attempts to cast the number ot a int64, returning
   685  // the result of the case or error if the case failed.
   686  func (n Number) Int64() (int64, error) {
   687  	return strconv.ParseInt(string(n), 10, 64)
   688  }
   689  
   690  // Uint64 attempts to cast the number ot a uint64, returning
   691  // the result of the case or error if the case failed.
   692  func (n Number) Uint64() (uint64, error) {
   693  	return strconv.ParseUint(string(n), 10, 64)
   694  }
   695  
   696  // String returns the raw number represented as a string
   697  func (n Number) String() string {
   698  	return string(n)
   699  }
   700  
   701  type emptyOrigError struct{}
   702  
   703  func (e emptyOrigError) OrigErr() error {
   704  	return nil
   705  }
   706  
   707  // An UnmarshalTypeError is an error type representing a error
   708  // unmarshaling the AttributeValue's element to a Go value type.
   709  // Includes details about the AttributeValue type and Go value type.
   710  type UnmarshalTypeError struct {
   711  	emptyOrigError
   712  	Value string
   713  	Type  reflect.Type
   714  }
   715  
   716  // Error returns the string representation of the error.
   717  // satisfying the error interface
   718  func (e *UnmarshalTypeError) Error() string {
   719  	return fmt.Sprintf("%s: %s", e.Code(), e.Message())
   720  }
   721  
   722  // Code returns the code of the error, satisfying the awserr.Error
   723  // interface.
   724  func (e *UnmarshalTypeError) Code() string {
   725  	return "UnmarshalTypeError"
   726  }
   727  
   728  // Message returns the detailed message of the error, satisfying
   729  // the awserr.Error interface.
   730  func (e *UnmarshalTypeError) Message() string {
   731  	return "cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
   732  }
   733  
   734  // An InvalidUnmarshalError is an error type representing an invalid type
   735  // encountered while unmarshaling a AttributeValue to a Go value type.
   736  type InvalidUnmarshalError struct {
   737  	emptyOrigError
   738  	Type reflect.Type
   739  }
   740  
   741  // Error returns the string representation of the error.
   742  // satisfying the error interface
   743  func (e *InvalidUnmarshalError) Error() string {
   744  	return fmt.Sprintf("%s: %s", e.Code(), e.Message())
   745  }
   746  
   747  // Code returns the code of the error, satisfying the awserr.Error
   748  // interface.
   749  func (e *InvalidUnmarshalError) Code() string {
   750  	return "InvalidUnmarshalError"
   751  }
   752  
   753  // Message returns the detailed message of the error, satisfying
   754  // the awserr.Error interface.
   755  func (e *InvalidUnmarshalError) Message() string {
   756  	if e.Type == nil {
   757  		return "cannot unmarshal to nil value"
   758  	}
   759  	if e.Type.Kind() != reflect.Ptr {
   760  		return "cannot unmarshal to non-pointer value, got " + e.Type.String()
   761  	}
   762  	return "cannot unmarshal to nil value, " + e.Type.String()
   763  }
   764  
   765  // An UnmarshalError wraps an error that occurred while unmarshaling a DynamoDB
   766  // AttributeValue element into a Go type. This is different from UnmarshalTypeError
   767  // in that it wraps the underlying error that occurred.
   768  type UnmarshalError struct {
   769  	Err   error
   770  	Value string
   771  	Type  reflect.Type
   772  }
   773  
   774  // Error returns the string representation of the error.
   775  // satisfying the error interface.
   776  func (e *UnmarshalError) Error() string {
   777  	return fmt.Sprintf("%s: %s\ncaused by: %v", e.Code(), e.Message(), e.Err)
   778  }
   779  
   780  // OrigErr returns the original error that caused this issue.
   781  func (e UnmarshalError) OrigErr() error {
   782  	return e.Err
   783  }
   784  
   785  // Code returns the code of the error, satisfying the awserr.Error
   786  // interface.
   787  func (e *UnmarshalError) Code() string {
   788  	return "UnmarshalError"
   789  }
   790  
   791  // Message returns the detailed message of the error, satisfying
   792  // the awserr.Error interface.
   793  func (e *UnmarshalError) Message() string {
   794  	return fmt.Sprintf("cannot unmarshal %q into %s.",
   795  		e.Value, e.Type.String())
   796  }