// Package json provides functions for marshaling and unmarshaling JSON in a format that is
// backwards-compatible with Amino JSON encoding. This mostly differs from encoding/json in
// encoding of integers (64-bit integers are encoded as strings, not numbers), and handling
// of interfaces (wrapped in an interface object with type/value keys).
//
// JSON tags (e.g. `json:"name,omitempty"`) are supported in the same way as encoding/json, as is
// custom marshaling overrides via the json.Marshaler and json.Unmarshaler interfaces.
//
// Note that not all JSON emitted by CometBFT is generated by this library; some is generated by
// encoding/json instead, and kept like that for backwards compatibility.
//
// Encoding of numbers uses strings for 64-bit integers (including unspecified ints), to improve
// compatibility with e.g. Javascript (which uses 64-bit floats for numbers, having 53-bit
// precision):
//
//	int32(32)  // Output: 32
//	uint32(32) // Output: 32
//	int64(64)  // Output: "64"
//	uint64(64) // Output: "64"
//	int(64)    // Output: "64"
//	uint(64)   // Output: "64"
//
// Encoding of other scalars follows encoding/json:
//
//	nil   // Output: null
//	true  // Output: true
//	"foo" // Output: "foo"
//	""    // Output: ""
//
// Slices and arrays are encoded as encoding/json, including base64-encoding of byte slices
// with additional base64-encoding of byte arrays as well:
//
//	[]int64(nil)      // Output: null
//	[]int64{}         // Output: []
//	[]int64{1, 2, 3}  // Output: ["1", "2", "3"]
//	[]int32{1, 2, 3}  // Output: [1, 2, 3]
//	[]byte{1, 2, 3}   // Output: "AQID"
//	[3]int64{1, 2, 3} // Output: ["1", "2", "3"]
//	[3]byte{1, 2, 3}  // Output: "AQID"
//
// Maps are encoded as encoding/json, but only strings are allowed as map keys (nil maps are not
// emitted as null, to retain Amino backwards-compatibility):
//
//	map[string]int64(nil)          // Output: {}
//	map[string]int64{}             // Output: {}
//	map[string]int64{"a":1,"b":2}  // Output: {"a":"1","b":"2"}
//	map[string]int32{"a":1,"b":2}  // Output: {"a":1,"b":2}
//	map[bool]int{true:1}           // Errors
//
// Times are encoded as encoding/json, in RFC3339Nano format, but requiring UTC time zone (with zero
// times emitted as "0001-01-01T00:00:00Z" as with encoding/json):
//
//	time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
//	// Output: "2020-06-08T14:21:28.000000123Z"
//	time.Time{}       // Output: "0001-01-01T00:00:00Z"
//	(*time.Time)(nil) // Output: null
//
// Structs are encoded as encoding/json, supporting JSON tags and ignoring private fields:
//
//	type Struct struct{
//		Name    string
//		Value   int32 `json:"value,omitempty"`
//		private bool
//	}
//
//	Struct{Name: "foo", Value: 7, private: true} // Output: {"Name":"foo","value":7}
//	Struct{} // Output: {"Name":""}
//
// Registered types are encoded with type wrapper, regardless of whether they are given as interface
// or bare struct, but inside structs they are only emitted with type wrapper for interface fields
// (this follows Amino behavior):
//
//	type Vehicle interface {
//		Drive() error
//	}
//
//	type Car struct {
//		Wheels int8
//	}
//
//	func (c *Car) Drive() error { return nil }
//
//	RegisterType(&Car{}, "vehicle/car")
//
//	Car{Wheels: 4}           // Output: {"type":"vehicle/car","value":{"Wheels":4}}
//	&Car{Wheels: 4}          // Output: {"type":"vehicle/car","value":{"Wheels":4}}
//	(*Car)(nil)              // Output: null
//	Vehicle(Car{Wheels: 4})  // Output: {"type":"vehicle/car","value":{"Wheels":4}}
//	Vehicle(nil)             // Output: null
//
//	type Struct struct {
//		Car *Car
//		Vehicle Vehicle
//	}
//
//	Struct{Car: &Car{Wheels: 4}, Vehicle: &Car{Wheels: 4}}
//	// Output: {"Car": {"Wheels: 4"}, "Vehicle": {"type":"vehicle/car","value":{"Wheels":4}}}
package json
