decoder.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. package apijson
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "reflect"
  7. "strconv"
  8. "sync"
  9. "time"
  10. "unsafe"
  11. "github.com/tidwall/gjson"
  12. )
  13. // decoders is a synchronized map with roughly the following type:
  14. // map[reflect.Type]decoderFunc
  15. var decoders sync.Map
  16. // Unmarshal is similar to [encoding/json.Unmarshal] and parses the JSON-encoded
  17. // data and stores it in the given pointer.
  18. func Unmarshal(raw []byte, to any) error {
  19. d := &decoderBuilder{dateFormat: time.RFC3339}
  20. return d.unmarshal(raw, to)
  21. }
  22. // UnmarshalRoot is like Unmarshal, but doesn't try to call MarshalJSON on the
  23. // root element. Useful if a struct's UnmarshalJSON is overrode to use the
  24. // behavior of this encoder versus the standard library.
  25. func UnmarshalRoot(raw []byte, to any) error {
  26. d := &decoderBuilder{dateFormat: time.RFC3339, root: true}
  27. return d.unmarshal(raw, to)
  28. }
  29. // decoderBuilder contains the 'compile-time' state of the decoder.
  30. type decoderBuilder struct {
  31. // Whether or not this is the first element and called by [UnmarshalRoot], see
  32. // the documentation there to see why this is necessary.
  33. root bool
  34. // The dateFormat (a format string for [time.Format]) which is chosen by the
  35. // last struct tag that was seen.
  36. dateFormat string
  37. }
  38. // decoderState contains the 'run-time' state of the decoder.
  39. type decoderState struct {
  40. strict bool
  41. exactness exactness
  42. }
  43. // Exactness refers to how close to the type the result was if deserialization
  44. // was successful. This is useful in deserializing unions, where you want to try
  45. // each entry, first with strict, then with looser validation, without actually
  46. // having to do a lot of redundant work by marshalling twice (or maybe even more
  47. // times).
  48. type exactness int8
  49. const (
  50. // Some values had to fudged a bit, for example by converting a string to an
  51. // int, or an enum with extra values.
  52. loose exactness = iota
  53. // There are some extra arguments, but other wise it matches the union.
  54. extras
  55. // Exactly right.
  56. exact
  57. )
  58. type decoderFunc func(node gjson.Result, value reflect.Value, state *decoderState) error
  59. type decoderField struct {
  60. tag parsedStructTag
  61. fn decoderFunc
  62. idx []int
  63. goname string
  64. }
  65. type decoderEntry struct {
  66. reflect.Type
  67. dateFormat string
  68. root bool
  69. }
  70. func (d *decoderBuilder) unmarshal(raw []byte, to any) error {
  71. value := reflect.ValueOf(to).Elem()
  72. result := gjson.ParseBytes(raw)
  73. if !value.IsValid() {
  74. return fmt.Errorf("apijson: cannot marshal into invalid value")
  75. }
  76. return d.typeDecoder(value.Type())(result, value, &decoderState{strict: false, exactness: exact})
  77. }
  78. func (d *decoderBuilder) typeDecoder(t reflect.Type) decoderFunc {
  79. entry := decoderEntry{
  80. Type: t,
  81. dateFormat: d.dateFormat,
  82. root: d.root,
  83. }
  84. if fi, ok := decoders.Load(entry); ok {
  85. return fi.(decoderFunc)
  86. }
  87. // To deal with recursive types, populate the map with an
  88. // indirect func before we build it. This type waits on the
  89. // real func (f) to be ready and then calls it. This indirect
  90. // func is only used for recursive types.
  91. var (
  92. wg sync.WaitGroup
  93. f decoderFunc
  94. )
  95. wg.Add(1)
  96. fi, loaded := decoders.LoadOrStore(entry, decoderFunc(func(node gjson.Result, v reflect.Value, state *decoderState) error {
  97. wg.Wait()
  98. return f(node, v, state)
  99. }))
  100. if loaded {
  101. return fi.(decoderFunc)
  102. }
  103. // Compute the real decoder and replace the indirect func with it.
  104. f = d.newTypeDecoder(t)
  105. wg.Done()
  106. decoders.Store(entry, f)
  107. return f
  108. }
  109. func indirectUnmarshalerDecoder(n gjson.Result, v reflect.Value, state *decoderState) error {
  110. return v.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw))
  111. }
  112. func unmarshalerDecoder(n gjson.Result, v reflect.Value, state *decoderState) error {
  113. if v.Kind() == reflect.Pointer && v.CanSet() {
  114. v.Set(reflect.New(v.Type().Elem()))
  115. }
  116. return v.Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw))
  117. }
  118. func (d *decoderBuilder) newTypeDecoder(t reflect.Type) decoderFunc {
  119. if t.ConvertibleTo(reflect.TypeOf(time.Time{})) {
  120. return d.newTimeTypeDecoder(t)
  121. }
  122. if !d.root && t.Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()) {
  123. return unmarshalerDecoder
  124. }
  125. if !d.root && reflect.PointerTo(t).Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()) {
  126. if _, ok := unionVariants[t]; !ok {
  127. return indirectUnmarshalerDecoder
  128. }
  129. }
  130. d.root = false
  131. if _, ok := unionRegistry[t]; ok {
  132. return d.newUnionDecoder(t)
  133. }
  134. switch t.Kind() {
  135. case reflect.Pointer:
  136. inner := t.Elem()
  137. innerDecoder := d.typeDecoder(inner)
  138. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  139. if !v.IsValid() {
  140. return fmt.Errorf("apijson: unexpected invalid reflection value %+#v", v)
  141. }
  142. newValue := reflect.New(inner).Elem()
  143. err := innerDecoder(n, newValue, state)
  144. if err != nil {
  145. return err
  146. }
  147. v.Set(newValue.Addr())
  148. return nil
  149. }
  150. case reflect.Struct:
  151. return d.newStructTypeDecoder(t)
  152. case reflect.Array:
  153. fallthrough
  154. case reflect.Slice:
  155. return d.newArrayTypeDecoder(t)
  156. case reflect.Map:
  157. return d.newMapDecoder(t)
  158. case reflect.Interface:
  159. return func(node gjson.Result, value reflect.Value, state *decoderState) error {
  160. if !value.IsValid() {
  161. return fmt.Errorf("apijson: unexpected invalid value %+#v", value)
  162. }
  163. if node.Value() != nil && value.CanSet() {
  164. value.Set(reflect.ValueOf(node.Value()))
  165. }
  166. return nil
  167. }
  168. default:
  169. return d.newPrimitiveTypeDecoder(t)
  170. }
  171. }
  172. // newUnionDecoder returns a decoderFunc that deserializes into a union using an
  173. // algorithm roughly similar to Pydantic's [smart algorithm].
  174. //
  175. // Conceptually this is equivalent to choosing the best schema based on how 'exact'
  176. // the deserialization is for each of the schemas.
  177. //
  178. // If there is a tie in the level of exactness, then the tie is broken
  179. // left-to-right.
  180. //
  181. // [smart algorithm]: https://docs.pydantic.dev/latest/concepts/unions/#smart-mode
  182. func (d *decoderBuilder) newUnionDecoder(t reflect.Type) decoderFunc {
  183. unionEntry, ok := unionRegistry[t]
  184. if !ok {
  185. panic("apijson: couldn't find union of type " + t.String() + " in union registry")
  186. }
  187. decoders := []decoderFunc{}
  188. for _, variant := range unionEntry.variants {
  189. decoder := d.typeDecoder(variant.Type)
  190. decoders = append(decoders, decoder)
  191. }
  192. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  193. // If there is a discriminator match, circumvent the exactness logic entirely
  194. for idx, variant := range unionEntry.variants {
  195. decoder := decoders[idx]
  196. if variant.TypeFilter != n.Type {
  197. continue
  198. }
  199. if len(unionEntry.discriminatorKey) != 0 {
  200. discriminatorValue := n.Get(unionEntry.discriminatorKey).Value()
  201. if discriminatorValue == variant.DiscriminatorValue {
  202. inner := reflect.New(variant.Type).Elem()
  203. err := decoder(n, inner, state)
  204. v.Set(inner)
  205. return err
  206. }
  207. }
  208. }
  209. // Set bestExactness to worse than loose
  210. bestExactness := loose - 1
  211. for idx, variant := range unionEntry.variants {
  212. decoder := decoders[idx]
  213. if variant.TypeFilter != n.Type {
  214. continue
  215. }
  216. sub := decoderState{strict: state.strict, exactness: exact}
  217. inner := reflect.New(variant.Type).Elem()
  218. err := decoder(n, inner, &sub)
  219. if err != nil {
  220. continue
  221. }
  222. if sub.exactness == exact {
  223. v.Set(inner)
  224. return nil
  225. }
  226. if sub.exactness > bestExactness {
  227. v.Set(inner)
  228. bestExactness = sub.exactness
  229. }
  230. }
  231. if bestExactness < loose {
  232. return errors.New("apijson: was not able to coerce type as union")
  233. }
  234. if guardStrict(state, bestExactness != exact) {
  235. return errors.New("apijson: was not able to coerce type as union strictly")
  236. }
  237. return nil
  238. }
  239. }
  240. func (d *decoderBuilder) newMapDecoder(t reflect.Type) decoderFunc {
  241. keyType := t.Key()
  242. itemType := t.Elem()
  243. itemDecoder := d.typeDecoder(itemType)
  244. return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) {
  245. mapValue := reflect.MakeMapWithSize(t, len(node.Map()))
  246. node.ForEach(func(key, value gjson.Result) bool {
  247. // It's fine for us to just use `ValueOf` here because the key types will
  248. // always be primitive types so we don't need to decode it using the standard pattern
  249. keyValue := reflect.ValueOf(key.Value())
  250. if !keyValue.IsValid() {
  251. if err == nil {
  252. err = fmt.Errorf("apijson: received invalid key type %v", keyValue.String())
  253. }
  254. return false
  255. }
  256. if keyValue.Type() != keyType {
  257. if err == nil {
  258. err = fmt.Errorf("apijson: expected key type %v but got %v", keyType, keyValue.Type())
  259. }
  260. return false
  261. }
  262. itemValue := reflect.New(itemType).Elem()
  263. itemerr := itemDecoder(value, itemValue, state)
  264. if itemerr != nil {
  265. if err == nil {
  266. err = itemerr
  267. }
  268. return false
  269. }
  270. mapValue.SetMapIndex(keyValue, itemValue)
  271. return true
  272. })
  273. if err != nil {
  274. return err
  275. }
  276. value.Set(mapValue)
  277. return nil
  278. }
  279. }
  280. func (d *decoderBuilder) newArrayTypeDecoder(t reflect.Type) decoderFunc {
  281. itemDecoder := d.typeDecoder(t.Elem())
  282. return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) {
  283. if !node.IsArray() {
  284. return fmt.Errorf("apijson: could not deserialize to an array")
  285. }
  286. arrayNode := node.Array()
  287. arrayValue := reflect.MakeSlice(reflect.SliceOf(t.Elem()), len(arrayNode), len(arrayNode))
  288. for i, itemNode := range arrayNode {
  289. err = itemDecoder(itemNode, arrayValue.Index(i), state)
  290. if err != nil {
  291. return err
  292. }
  293. }
  294. value.Set(arrayValue)
  295. return nil
  296. }
  297. }
  298. func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
  299. // map of json field name to struct field decoders
  300. decoderFields := map[string]decoderField{}
  301. anonymousDecoders := []decoderField{}
  302. extraDecoder := (*decoderField)(nil)
  303. inlineDecoder := (*decoderField)(nil)
  304. for i := 0; i < t.NumField(); i++ {
  305. idx := []int{i}
  306. field := t.FieldByIndex(idx)
  307. if !field.IsExported() {
  308. continue
  309. }
  310. // If this is an embedded struct, traverse one level deeper to extract
  311. // the fields and get their encoders as well.
  312. if field.Anonymous {
  313. anonymousDecoders = append(anonymousDecoders, decoderField{
  314. fn: d.typeDecoder(field.Type),
  315. idx: idx[:],
  316. })
  317. continue
  318. }
  319. // If json tag is not present, then we skip, which is intentionally
  320. // different behavior from the stdlib.
  321. ptag, ok := parseJSONStructTag(field)
  322. if !ok {
  323. continue
  324. }
  325. // We only want to support unexported fields if they're tagged with
  326. // `extras` because that field shouldn't be part of the public API.
  327. if ptag.extras {
  328. extraDecoder = &decoderField{ptag, d.typeDecoder(field.Type.Elem()), idx, field.Name}
  329. continue
  330. }
  331. if ptag.inline {
  332. inlineDecoder = &decoderField{ptag, d.typeDecoder(field.Type), idx, field.Name}
  333. continue
  334. }
  335. if ptag.metadata {
  336. continue
  337. }
  338. oldFormat := d.dateFormat
  339. dateFormat, ok := parseFormatStructTag(field)
  340. if ok {
  341. switch dateFormat {
  342. case "date-time":
  343. d.dateFormat = time.RFC3339
  344. case "date":
  345. d.dateFormat = "2006-01-02"
  346. }
  347. }
  348. decoderFields[ptag.name] = decoderField{ptag, d.typeDecoder(field.Type), idx, field.Name}
  349. d.dateFormat = oldFormat
  350. }
  351. return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) {
  352. if field := value.FieldByName("JSON"); field.IsValid() {
  353. if raw := field.FieldByName("raw"); raw.IsValid() {
  354. setUnexportedField(raw, node.Raw)
  355. }
  356. }
  357. for _, decoder := range anonymousDecoders {
  358. // ignore errors
  359. decoder.fn(node, value.FieldByIndex(decoder.idx), state)
  360. }
  361. if inlineDecoder != nil {
  362. var meta Field
  363. dest := value.FieldByIndex(inlineDecoder.idx)
  364. isValid := false
  365. if dest.IsValid() && node.Type != gjson.Null {
  366. err = inlineDecoder.fn(node, dest, state)
  367. if err == nil {
  368. isValid = true
  369. }
  370. }
  371. if node.Type == gjson.Null {
  372. meta = Field{
  373. raw: node.Raw,
  374. status: null,
  375. }
  376. } else if !isValid {
  377. meta = Field{
  378. raw: node.Raw,
  379. status: invalid,
  380. }
  381. } else if isValid {
  382. meta = Field{
  383. raw: node.Raw,
  384. status: valid,
  385. }
  386. }
  387. if metadata := getSubField(value, inlineDecoder.idx, inlineDecoder.goname); metadata.IsValid() {
  388. metadata.Set(reflect.ValueOf(meta))
  389. }
  390. return err
  391. }
  392. typedExtraType := reflect.Type(nil)
  393. typedExtraFields := reflect.Value{}
  394. if extraDecoder != nil {
  395. typedExtraType = value.FieldByIndex(extraDecoder.idx).Type()
  396. typedExtraFields = reflect.MakeMap(typedExtraType)
  397. }
  398. untypedExtraFields := map[string]Field{}
  399. for fieldName, itemNode := range node.Map() {
  400. df, explicit := decoderFields[fieldName]
  401. var (
  402. dest reflect.Value
  403. fn decoderFunc
  404. meta Field
  405. )
  406. if explicit {
  407. fn = df.fn
  408. dest = value.FieldByIndex(df.idx)
  409. }
  410. if !explicit && extraDecoder != nil {
  411. dest = reflect.New(typedExtraType.Elem()).Elem()
  412. fn = extraDecoder.fn
  413. }
  414. isValid := false
  415. if dest.IsValid() && itemNode.Type != gjson.Null {
  416. err = fn(itemNode, dest, state)
  417. if err == nil {
  418. isValid = true
  419. }
  420. }
  421. if itemNode.Type == gjson.Null {
  422. meta = Field{
  423. raw: itemNode.Raw,
  424. status: null,
  425. }
  426. } else if !isValid {
  427. meta = Field{
  428. raw: itemNode.Raw,
  429. status: invalid,
  430. }
  431. } else if isValid {
  432. meta = Field{
  433. raw: itemNode.Raw,
  434. status: valid,
  435. }
  436. }
  437. if explicit {
  438. if metadata := getSubField(value, df.idx, df.goname); metadata.IsValid() {
  439. metadata.Set(reflect.ValueOf(meta))
  440. }
  441. }
  442. if !explicit {
  443. untypedExtraFields[fieldName] = meta
  444. }
  445. if !explicit && extraDecoder != nil {
  446. typedExtraFields.SetMapIndex(reflect.ValueOf(fieldName), dest)
  447. }
  448. }
  449. if extraDecoder != nil && typedExtraFields.Len() > 0 {
  450. value.FieldByIndex(extraDecoder.idx).Set(typedExtraFields)
  451. }
  452. // Set exactness to 'extras' if there are untyped, extra fields.
  453. if len(untypedExtraFields) > 0 && state.exactness > extras {
  454. state.exactness = extras
  455. }
  456. if metadata := getSubField(value, []int{-1}, "ExtraFields"); metadata.IsValid() && len(untypedExtraFields) > 0 {
  457. metadata.Set(reflect.ValueOf(untypedExtraFields))
  458. }
  459. return nil
  460. }
  461. }
  462. func (d *decoderBuilder) newPrimitiveTypeDecoder(t reflect.Type) decoderFunc {
  463. switch t.Kind() {
  464. case reflect.String:
  465. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  466. v.SetString(n.String())
  467. if guardStrict(state, n.Type != gjson.String) {
  468. return fmt.Errorf("apijson: failed to parse string strictly")
  469. }
  470. // Everything that is not an object can be loosely stringified.
  471. if n.Type == gjson.JSON {
  472. return fmt.Errorf("apijson: failed to parse string")
  473. }
  474. if guardUnknown(state, v) {
  475. return fmt.Errorf("apijson: failed string enum validation")
  476. }
  477. return nil
  478. }
  479. case reflect.Bool:
  480. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  481. v.SetBool(n.Bool())
  482. if guardStrict(state, n.Type != gjson.True && n.Type != gjson.False) {
  483. return fmt.Errorf("apijson: failed to parse bool strictly")
  484. }
  485. // Numbers and strings that are either 'true' or 'false' can be loosely
  486. // deserialized as bool.
  487. if n.Type == gjson.String && (n.Raw != "true" && n.Raw != "false") || n.Type == gjson.JSON {
  488. return fmt.Errorf("apijson: failed to parse bool")
  489. }
  490. if guardUnknown(state, v) {
  491. return fmt.Errorf("apijson: failed bool enum validation")
  492. }
  493. return nil
  494. }
  495. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  496. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  497. v.SetInt(n.Int())
  498. if guardStrict(state, n.Type != gjson.Number || n.Num != float64(int(n.Num))) {
  499. return fmt.Errorf("apijson: failed to parse int strictly")
  500. }
  501. // Numbers, booleans, and strings that maybe look like numbers can be
  502. // loosely deserialized as numbers.
  503. if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) {
  504. return fmt.Errorf("apijson: failed to parse int")
  505. }
  506. if guardUnknown(state, v) {
  507. return fmt.Errorf("apijson: failed int enum validation")
  508. }
  509. return nil
  510. }
  511. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  512. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  513. v.SetUint(n.Uint())
  514. if guardStrict(state, n.Type != gjson.Number || n.Num != float64(int(n.Num)) || n.Num < 0) {
  515. return fmt.Errorf("apijson: failed to parse uint strictly")
  516. }
  517. // Numbers, booleans, and strings that maybe look like numbers can be
  518. // loosely deserialized as uint.
  519. if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) {
  520. return fmt.Errorf("apijson: failed to parse uint")
  521. }
  522. if guardUnknown(state, v) {
  523. return fmt.Errorf("apijson: failed uint enum validation")
  524. }
  525. return nil
  526. }
  527. case reflect.Float32, reflect.Float64:
  528. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  529. v.SetFloat(n.Float())
  530. if guardStrict(state, n.Type != gjson.Number) {
  531. return fmt.Errorf("apijson: failed to parse float strictly")
  532. }
  533. // Numbers, booleans, and strings that maybe look like numbers can be
  534. // loosely deserialized as floats.
  535. if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) {
  536. return fmt.Errorf("apijson: failed to parse float")
  537. }
  538. if guardUnknown(state, v) {
  539. return fmt.Errorf("apijson: failed float enum validation")
  540. }
  541. return nil
  542. }
  543. default:
  544. return func(node gjson.Result, v reflect.Value, state *decoderState) error {
  545. return fmt.Errorf("unknown type received at primitive decoder: %s", t.String())
  546. }
  547. }
  548. }
  549. func (d *decoderBuilder) newTimeTypeDecoder(t reflect.Type) decoderFunc {
  550. format := d.dateFormat
  551. return func(n gjson.Result, v reflect.Value, state *decoderState) error {
  552. parsed, err := time.Parse(format, n.Str)
  553. if err == nil {
  554. v.Set(reflect.ValueOf(parsed).Convert(t))
  555. return nil
  556. }
  557. if guardStrict(state, true) {
  558. return err
  559. }
  560. layouts := []string{
  561. "2006-01-02",
  562. "2006-01-02T15:04:05Z07:00",
  563. "2006-01-02T15:04:05Z0700",
  564. "2006-01-02T15:04:05",
  565. "2006-01-02 15:04:05Z07:00",
  566. "2006-01-02 15:04:05Z0700",
  567. "2006-01-02 15:04:05",
  568. }
  569. for _, layout := range layouts {
  570. parsed, err := time.Parse(layout, n.Str)
  571. if err == nil {
  572. v.Set(reflect.ValueOf(parsed).Convert(t))
  573. return nil
  574. }
  575. }
  576. return fmt.Errorf("unable to leniently parse date-time string: %s", n.Str)
  577. }
  578. }
  579. func setUnexportedField(field reflect.Value, value interface{}) {
  580. reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Set(reflect.ValueOf(value))
  581. }
  582. func guardStrict(state *decoderState, cond bool) bool {
  583. if !cond {
  584. return false
  585. }
  586. if state.strict {
  587. return true
  588. }
  589. state.exactness = loose
  590. return false
  591. }
  592. func canParseAsNumber(str string) bool {
  593. _, err := strconv.ParseFloat(str, 64)
  594. return err == nil
  595. }
  596. func guardUnknown(state *decoderState, v reflect.Value) bool {
  597. if have, ok := v.Interface().(interface{ IsKnown() bool }); guardStrict(state, ok && !have.IsKnown()) {
  598. return true
  599. }
  600. return false
  601. }