json

package
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2023 License: Apache-2.0 Imports: 11 Imported by: 4

Documentation

Overview

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 Tendermint 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}}}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(v interface{}) ([]byte, error)

Marshal marshals the value as JSON, using Amino-compatible JSON encoding (strings for 64-bit numbers, and type wrappers for registered types).

func MarshalIndent

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

MarshalIndent marshals the value as JSON, using the given prefix and indentation.

func RegisterType

func RegisterType(_type interface{}, name string)

RegisterType registers a type for Amino-compatible interface encoding in the global type registry. These types will be encoded with a type wrapper `{"type":"<type>","value":<value>}` regardless of which interface they are wrapped in (if any). If the type is a pointer, it will still be valid both for value and pointer types, but decoding into an interface will generate the a value or pointer based on the registered type.

Should only be called in init() functions, as it panics on error.

func Unmarshal

func Unmarshal(bz []byte, v interface{}) error

Unmarshal unmarshals JSON into the given value, using Amino-compatible JSON encoding (strings for 64-bit numbers, and type wrappers for registered types).

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL