decode.go 21 KB

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