You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.8 KiB

  1. // Package json provides functions for marshaling and unmarshaling JSON in a format that is
  2. // backwards-compatible with Amino JSON encoding. This mostly differs from encoding/json in
  3. // encoding of integers (64-bit integers are encoded as strings, not numbers), and handling
  4. // of interfaces (wrapped in an interface object with type/value keys).
  5. //
  6. // JSON tags (e.g. `json:"name,omitempty"`) are supported in the same way as encoding/json, as is
  7. // custom marshaling overrides via the json.Marshaler and json.Unmarshaler interfaces.
  8. //
  9. // Note that not all JSON emitted by Tendermint is generated by this library; some is generated by
  10. // encoding/json instead, and kept like that for backwards compatibility.
  11. //
  12. // Encoding of numbers uses strings for 64-bit integers (including unspecified ints), to improve
  13. // compatibility with e.g. Javascript (which uses 64-bit floats for numbers, having 53-bit
  14. // precision):
  15. //
  16. // int32(32) // Output: 32
  17. // uint32(32) // Output: 32
  18. // int64(64) // Output: "64"
  19. // uint64(64) // Output: "64"
  20. // int(64) // Output: "64"
  21. // uint(64) // Output: "64"
  22. //
  23. // Encoding of other scalars follows encoding/json:
  24. //
  25. // nil // Output: null
  26. // true // Output: true
  27. // "foo" // Output: "foo"
  28. // "" // Output: ""
  29. //
  30. // Slices and arrays are encoded as encoding/json, including base64-encoding of byte slices
  31. // with additional base64-encoding of byte arrays as well:
  32. //
  33. // []int64(nil) // Output: null
  34. // []int64{} // Output: []
  35. // []int64{1, 2, 3} // Output: ["1", "2", "3"]
  36. // []int32{1, 2, 3} // Output: [1, 2, 3]
  37. // []byte{1, 2, 3} // Output: "AQID"
  38. // [3]int64{1, 2, 3} // Output: ["1", "2", "3"]
  39. // [3]byte{1, 2, 3} // Output: "AQID"
  40. //
  41. // Maps are encoded as encoding/json, but only strings are allowed as map keys (nil maps are not
  42. // emitted as null, to retain Amino backwards-compatibility):
  43. //
  44. // map[string]int64(nil) // Output: {}
  45. // map[string]int64{} // Output: {}
  46. // map[string]int64{"a":1,"b":2} // Output: {"a":"1","b":"2"}
  47. // map[string]int32{"a":1,"b":2} // Output: {"a":1,"b":2}
  48. // map[bool]int{true:1} // Errors
  49. //
  50. // Times are encoded as encoding/json, in RFC3339Nano format, but requiring UTC time zone (with zero
  51. // times emitted as "0001-01-01T00:00:00Z" as with encoding/json):
  52. //
  53. // time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
  54. // // Output: "2020-06-08T14:21:28.000000123Z"
  55. // time.Time{} // Output: "0001-01-01T00:00:00Z"
  56. // (*time.Time)(nil) // Output: null
  57. //
  58. // Structs are encoded as encoding/json, supporting JSON tags and ignoring private fields:
  59. //
  60. // type Struct struct{
  61. // Name string
  62. // Value int32 `json:"value,omitempty"`
  63. // private bool
  64. // }
  65. //
  66. // Struct{Name: "foo", Value: 7, private: true} // Output: {"Name":"foo","value":7}
  67. // Struct{} // Output: {"Name":""}
  68. //
  69. // Registered types are encoded with type wrapper, regardless of whether they are given as interface
  70. // or bare struct, but inside structs they are only emitted with type wrapper for interface fields
  71. // (this follows Amino behavior):
  72. //
  73. // type Vehicle interface {
  74. // Drive() error
  75. // }
  76. //
  77. // type Car struct {
  78. // Wheels int8
  79. // }
  80. //
  81. // func (c *Car) Drive() error { return nil }
  82. //
  83. // RegisterType(&Car{}, "vehicle/car")
  84. //
  85. // Car{Wheels: 4} // Output: {"type":"vehicle/car","value":{"Wheels":4}}
  86. // &Car{Wheels: 4} // Output: {"type":"vehicle/car","value":{"Wheels":4}}
  87. // (*Car)(nil) // Output: null
  88. // Vehicle(Car{Wheels: 4}) // Output: {"type":"vehicle/car","value":{"Wheels":4}}
  89. // Vehicle(nil) // Output: null
  90. //
  91. // type Struct struct {
  92. // Car *Car
  93. // Vehicle Vehicle
  94. // }
  95. //
  96. // Struct{Car: &Car{Wheels: 4}, Vehicle: &Car{Wheels: 4}}
  97. // // Output: {"Car": {"Wheels: 4"}, "Vehicle": {"type":"vehicle/car","value":{"Wheels":4}}}
  98. //
  99. package json