gojson

package module
v1.0.21 Latest Latest
Warning

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

Go to latest
Published: Nov 16, 2023 License: MIT Imports: 12 Imported by: 7

README

gojson

gojson is a collection of tools for extracting meaningful information from a JSON encoded string, including unmarshaling and single-value extraction. gojson is a read only structure. It was born out of a need to extract untrusted JSON into a struct in a type-safe manner.

One of the major problems that caused gojson to be born was a lack of JSON Type homogeneity for a given field. Numbers were often mixed as JSON Numbers and JSON Strings.

The tests for gojson attempt to be illustrative. If you have a question on usage not found here, try reading / modifying the tests to get an idea of how it performs.

JSON Types

JSON has six major types: JSONObject, JSONArray, JSONString, JSONNumber, JSONBoolean, JSONNull

The data found in a JSON field might not always be the type you wish it to be. Consider the following small example program:

package main

import (
	"encoding/json"
	"fmt"

	"github.com/btm6084/gojson"
)

func main() {
	data := [][]byte{
		[]byte(`{"open_new_window": true}`),
		[]byte(`{"open_new_window": 1}`),
		[]byte(`{"open_new_window": "1"}`),
		[]byte(`{"open_new_window": "true"}`),
		[]byte(`{"open_new_window": "t"}`),
		[]byte(`{"open_new_window": 1.0}`),
	}

	type BusinessRules struct {
		OpenNewWindow bool `json:"open_new_window"`
	}

	fmt.Println("Encoding/JSON")
	for _, d := range data {
		var br BusinessRules

		fmt.Println(json.Unmarshal(d, &br), br)
	}

	fmt.Println()
	fmt.Println("gojson")
	for _, d := range data {
		var br BusinessRules

		fmt.Println(gojson.Unmarshal(d, &br), br)
	}
}

For each of these we want the same goal: We want BusinessRules.OpenNewWindow to be boolean true. However, if we try to use encoding/json.Unmarshal, all but one of these will error. When we use gojson.Unmarshal, we get what we actually want: BusinessRules.OpenNewWindow for every case.

Here's the output:

Encoding/JSON
<nil> {true}
json: cannot unmarshal number into Go struct field BusinessRules.open_new_window of type bool {false}
json: cannot unmarshal string into Go struct field BusinessRules.open_new_window of type bool {false}
json: cannot unmarshal string into Go struct field BusinessRules.open_new_window of type bool {false}
json: cannot unmarshal string into Go struct field BusinessRules.open_new_window of type bool {false}
json: cannot unmarshal number into Go struct field BusinessRules.open_new_window of type bool {false}

gojson
<nil> {true}
<nil> {true}
<nil> {true}
<nil> {true}
<nil> {true}
<nil> {true}

Available Tools

The gojson operations exist to make meaningful JSON data extractions possible in instances where the unmarshaller is insufficient, cumbersome, or simply overkill.

Unmarshal

gojson offers a custom unmarshaler which is fully compatible with the json.Unmarshaller interface found in encoding/json. The gojson unmarshaler adds some extra capabilities which encoding/json does not.

Struct Tags

gojson adds support for some new json tags when Unmarshaling

Flag Use
required An error will be returned if the required key does not exist in the subject JSON
nonempty An error will be returned if the required key does not exist in the subject JSON OR if it exists, but is the zero value for the json type.

Zero Values are as follows:

Type Value
JSONString ""
JSONInt 0
JSONFloat 0 or 0.0
JSONArray []
JSONObject {}
JSONBool false
JSONNull undefined

GoJSON will also look for the presence of gojson tags prior to looking for json tags. If the gojson tag exists, it will be used for Unmarshalling. Otherwise, the json tag will be used. This is useful for times when you wish to have separate behavior when Unmarshaling via gojson, and marshalling via encoding/json.

Example:

package main

import (
	"encoding/json"
	"fmt"

	"github.com/btm6084/gojson"
)

type Example struct {
	Product string `json:"-" gojson:"product"`
}

func main() {
	data := []byte(`{"product": "some product identifier"}`)

	var e Example

	gojson.Unmarshal(data, &e)
	fmt.Println(e.Product) // produces `some product identifier`

	m, _ := json.Marshal(e)
	fmt.Println(string(m)) // produces `{}`
}

Output:

some product identifier
{}
PostUnmarshalJSON

The gojson unmarshaller provides a new interface, PostUnmarshalJSON, defined as follow:

PostUnmarshalJSON([]byte, error) error

PostUnmarshalJSON is called after the unmarshal process has completed, and provides you with the original JSON byte string and any errors that came out of the unmarshal process. The receiver that you defined PostUnmarshalJSON for will be populated for use. This allows you to capture and recover from specific errors, allocate memory for empty slices/maps, react to missing date, perform operations based on the extracted data, or anything else that suits your need.

UnmarshalStrict

The default Unmarshal process tries to match the data to the container. This means if you have a json string with an integer, and you unmarshal that into an integer field, the conversion will happen for you automatially.

UnmarshalStrict, instead, attempts to match the container to the data, and will return an error if there is a mismatch.

Example:

package main

import (
	"fmt"

	"github.com/btm6084/gojson"
)

func main() {
	var container struct{
		Value int
	}

	data := []byte(`{"value": "12345"}`)

	err := gojson.UnmarshalStrict(data, &container)
	fmt.Println(container.Value, err)

	err = gojson.Unmarshal(data, &container)
	fmt.Println(container.Value, err)
}

Produces:

0 strict standards error, expected int, got string
12345 <nil>

Extract

The Extract* functions are designed to extract simple values from a json byte string without the need to unmarshal the entire structure. Simply pass in the JSON data and the key path, and you will receive the expected data (or an error, if that key does not exist).

  • Extract Extract(JSONData, Key) returns the data at the requested key, or an error if it doesn't exist. The return values are the data (as a byte slice), the JSON type of the data, and and errors.

  • ExtractReader ExtractReader will extract the requested segment and load it into a JSONReader object.

  • ExtractString ExtractString will extract the requested segment and return the value as a string.

  • ExtractInt ExtractString will extract the requested segment and return the value as an int.

  • ExtractFloat ExtractString will extract the requested segment and return the value as a float.

  • ExtractBool ExtractString will extract the requested segment and return the value as a bool.

  • ExtractInterface ExtractString will extract the requested segment and return the value as an interface.

Interface Type Conversions

JSON Type Interface Type
JSONInt int
JSONFloat float64
JSONString string
JSONBool bool
JSONNull interface{}(nil)
JSONArray []interface{}
JSONObject map[string]interface{}

JSONReader

One of the primary goals of gojson and the supporting tools is to give you a bit more power and influence over the unmarshal process without having to manually handle error conditions for every single field and element. JSONReader is designed to give you power over how you interact with JSON data.

Note that JSONReader parses the entire JSON byte string on instantiation, although subsequent lookups are indexed. This can be slower than you expect / need if you're not doing a large number of extractions / manipulations. If you only need a couple of fields, try Unmarshal or Extract*. If you need to query the object mutiple times, JSONReader might be a good option.

If you know your key is supposed to be an object, use Get. If you know your key is supposed to be an array, use GetCollection (returns a slice of gojson objects for you to loop over and continue extraction with) If you know your key is supposed to be an int, use GetInt If you know your key is supposed to be an array of ints, use GetIntSlice etc.

The To* functions return the root node's JSON data as the requested type.

  • ToBool
  • ToBoolSlice
  • ToByteSlice
  • ToByteSlices
  • ToFloat
  • ToFloatSlice
  • ToInt
  • ToInterface
  • ToInterfaceSlice
  • ToIntSlice
  • ToMapStringBool
  • ToMapStringBytes
  • ToMapStringFloat
  • ToMapStringInt
  • ToMapStringInterface
  • ToMapStringString
  • ToString
  • ToStringSlice

Get* functions require a key to extract.

  • Get
  • GetBool
  • GetBoolSlice
  • GetByteSlice
  • GetByteSlices
  • GetCollection
  • GetFloat
  • GetFloatSlice
  • GetInt
  • GetInterface
  • GetInterfaceSlice
  • GetIntSlice
  • GetMapStringInterface
  • GetString
  • GetStringSlice

Most data types have a function. Please see jsonreader.go for a full list.

The Get* functions return the requested type for nested values.

As a final note, gojson's Get* functions always return the Zero value if the key doesn't exist. This property, along with gojson's KeyExists() function, allows you to write quick and easy "isEmpty()" functions to check whether the data you received even has the right keys.

Example Program:

package main

import (
	"fmt"
	"log"

	"github.com/btm6084/gojson"
)

func main() {
	data := []byte(`{"documents": [{"city_name": "Some City", "postal_codes": ["123.45", 67890, 102.32, "0", true]}]}`)

	type City struct {
		Name     string `json:"city_name"`
		ZipCodes []int  `json:"postal_codes"`
	}

	reader, err := gojson.NewJSONReader(data)
	if err != nil {
		log.Fatal(err)
	}

	city := City{
		Name:     reader.GetString("documents.0.city_name"),
		ZipCodes: reader.GetIntSlice("documents.0.postal_codes"),
	}

	fmt.Println("City Name: ", city.Name)
	fmt.Println("Zip Codes: ", city.ZipCodes)
	fmt.Println()

	fmt.Println("Key                  : Value")
	fmt.Println()
	k := "documents.0.postal_codes"
	fmt.Printf("GetFloatSlice        : [%s]:[%#v] (%T)\n", k, reader.GetFloatSlice(k), reader.GetFloatSlice(k))
	fmt.Printf("GetMapStringInterface: [%s]:[%#v] (%T)\n", k, reader.GetMapStringInterface(k), reader.GetMapStringInterface(k))
	fmt.Println()

	subReader := reader.Get("documents.0.postal_codes")
	for _, k := range subReader.Keys {
		fmt.Printf("GetFloat             : [%s]:[%#v] (%T)\n", k, subReader.GetFloat(k), subReader.GetFloat(k))
		fmt.Printf("GetString            : [%s]:[%#v] (%T)\n", k, subReader.GetString(k), subReader.GetString(k))
		fmt.Printf("GetBool              : [%s]:[%#v] (%T)\n", k, subReader.GetBool(k), subReader.GetBool(k))
		fmt.Printf("GetInt               : [%s]:[%#v] (%T)\n", k, subReader.GetInt(k), subReader.GetInt(k))
		fmt.Println()
	}
	fmt.Println()
}

Output:

City Name:  Some City
Zip Codes:  [123 67890 102 0 1]

Key                  : Value

GetFloatSlice        : [documents.0.postal_codes]:[[]float64{123.45, 67890, 102.32, 0, 1}] ([]float64)
GetMapStringInterface: [documents.0.postal_codes]:[map[string]interface {}{"0":"123.45", "1":67890, "2":102.32, "3":"0", "4":true}] (map[string]interface {})

GetFloat             : [0]:[123.45] (float64)
GetString            : [0]:["123.45"] (string)
GetBool              : [0]:[false] (bool)
GetInt               : [0]:[123] (int)

GetFloat             : [1]:[67890] (float64)
GetString            : [1]:["67890"] (string)
GetBool              : [1]:[true] (bool)
GetInt               : [1]:[67890] (int)

GetFloat             : [2]:[102.32] (float64)
GetString            : [2]:["102.32"] (string)
GetBool              : [2]:[true] (bool)
GetInt               : [2]:[102] (int)

GetFloat             : [3]:[0] (float64)
GetString            : [3]:["0"] (string)
GetBool              : [3]:[false] (bool)
GetInt               : [3]:[0] (int)

GetFloat             : [4]:[1] (float64)
GetString            : [4]:["true"] (string)
GetBool              : [4]:[true] (bool)
GetInt               : [4]:[1] (int)

IsJSON Functions

GoJSON provides a number of Is* functions for use in validating JSON.

  • IsJSON
  • IsJSONArray
  • IsJSONFalse
  • IsJSONNull
  • IsJSONNumber
  • IsJSONObject
  • IsJSONString
  • IsJSONTrue

Tests

The tests for gojson attempt to be illustrative. If you have a question on usage not found here, try reading / modifying the tests to get an idea of how it performs.

Bonus Example

package main

import (
	"fmt"
	"log"

	"github.com/davecgh/go-spew/spew"
	"github.com/btm6084/gojson"
)

func main() {

	rawJSON := `{"value": "17", "name": "My Thing", "children": ["child1", "true", false, 17], "stuff": [ {"value": "4", "name": "stuff1"}, {"value": 5, "name": "stuff2"} ]}`

	type Thing struct {
		Value float64 `json:"value"`
		Name  string  `json:"name"`
	}

	type Things struct {
		Value    float64       `json:"value"`
		Name     string        `json:"name"`
		Children []interface{} `json:"children"`
		Stuff    []Thing       `json:"stuff"`
	}

	reader, err := gojson.NewJSONReader([]byte(rawJSON))
	if err != nil {
		log.Fatal(err)
	}

	t := Things{}

	t.Name = reader.GetString("name")
	t.Value = reader.GetFloat("value")
	t.Children = reader.GetInterfaceSlice("children")

	stuffs := reader.GetCollection("stuff")

	for _, s := range stuffs {
		t.Stuff = append(t.Stuff, Thing{
			s.GetFloat("value"),
			s.GetString("name"),
		})
	}

	fmt.Println(spew.Sdump(t))
}

Output:

(main.Things) {
	Value: (float64) 17,
	Name: (string) (len=8) "My Thing",
	Children: ([]interface {}) (len=4 cap=4) {
		(string) (len=6) "child1",
		(string) (len=4) "true",
		(bool) false,
		(int) 17
	},
	Stuff: ([]main.Thing) (len=2 cap=2) {
		(main.Thing) {
			Value: (float64) 4,
			Name: (string) (len=6) "stuff1"
		},
		(main.Thing) {
			Value: (float64) 5,
			Name: (string) (len=6) "stuff2"
		}
	}
}

Documentation

Index

Constants

View Source
const (
	// JSONNull denotes JSON value 'null'
	JSONNull = "null"

	// JSONBool denotes JSON values 'true' or 'false'
	JSONBool = "bool"

	// JSONInt denotes a JSON integer
	JSONInt = "int"

	// JSONFloat denotes a JSON floating point value
	JSONFloat = "float"

	// JSONString denotes a JSON string
	JSONString = "string"

	// JSONArray denotes a JSON array
	JSONArray = "array"

	// JSONObject denotes a JSON object
	JSONObject = "object"

	// JSONInvalid denotes a value that is not valid JSON
	JSONInvalid = ""
)

Variables

View Source
var (
	// ErrEndOfInput is returned when there are no further items to extract via Next()
	ErrEndOfInput = errors.New("Reached end of JSON Input")

	// ErrNoSuchIndex is returned when Index(n) is called and n does not exist.
	ErrNoSuchIndex = errors.New("Index does not exist")

	// ErrRequiresObject is returned when the input is neither an array or object.
	ErrRequiresObject = errors.New("NewIterator requires a valid JSONArray or JSONObject")
)
View Source
var (
	// ErrEmpty is returned when no input is provided.
	ErrEmpty = errors.New("empty input value")

	// ErrMalformedJSON is returned when input failed to parse.
	ErrMalformedJSON = errors.New("malformed json provided")
)
View Source
var (
	// ErrMergeType is returned when MergeJSON receives anything other than JSONObject or JSONArray
	ErrMergeType = errors.New("only JSONObject can be merged")
)

Functions

func Extract

func Extract(search []byte, path string) ([]byte, string, error)

Extract a specific key from a given JSON string. Returns value, type, and error.

Key Path Values: String, Number, and Constant not in a surrounding array or object will always

return the root, regardless of the key given.

Arrays will index from 0. Objects will will index as they are keyed. Empty key will always return whatever is at the root. Path is a period separated list of keys.

Examples:

data := []byte(`{
	"active": 0,
	"url": "http://www.example.com",
	"metadata": {
		"keywords": [
			"example",
			"sample",
			"illustration",
		],
		"error_code": 0
	}
}`)

Extract(data, "active") returns 0, "int", nil Extract(data, "url") returns "http://www.example.com", "string", nil Extract(data, "metadata.keywords.1") returns []byte(`"sample"`), "string", nil Extract(data, "metadata.error_code") returns []byte{'0'}, "int", nil Extract(data, "metadata.keywords.17") returns []byte(nil), "", "requested key 'metadata.keywords.17' doesn't exist

On return, a copy is made of the extracted data. This allows it to be modified without changing the original JSON.

func ExtractBool

func ExtractBool(search []byte, path string) (bool, error)

ExtractBool performs an Extract on the given JSON path. The resulting value is returned in the form of a bool. Numeric values are considered true if they are non-zero. String values are evaluated using strings.ParseBool. null is always false.

func ExtractFloat

func ExtractFloat(search []byte, path string) (float64, error)

ExtractFloat performs an Extract on the given JSON path. The resulting value is returned in the form of a float64.

func ExtractInt

func ExtractInt(search []byte, path string) (int, error)

ExtractInt performs an Extract on the given JSON path. The resulting value is returned in the form of an int.

func ExtractInterface

func ExtractInterface(search []byte, path string) (interface{}, string, error)

ExtractInterface performs an Extract on the given JSON path. The resulting value is returned in the form defined below. The returned type is the JSON type. These map as follows: json type -> interface{} type

JSONInt -> int JSONFloat -> float64 JSONString -> string JSONBool -> bool JSONNull -> interface{}(nil) JSONArray -> []interface{} JSONObject -> map[string]interface{}

func ExtractString

func ExtractString(search []byte, path string) (string, error)

ExtractString performs an Extract on the given JSON path. The resulting value is returned in the form of a string.

func GetJSONType

func GetJSONType(search []byte, start int) string

GetJSONType inspects the given byte string and attempts to identify the primary JSON type. JSONString, JSONInt, JSONFloat, JSONBool, JSONNull, JSONObject, or JSONArray JSONInvalid ("") denotes a JSON error.

Note that this is an early return guess. It's not guaranteed accurate if you send invalid JSON, as very little validation is performed for the sake of speed.

e.g. GetJSONType([]byte(`"No End Quote`), 0) would return JSONString, NOT JSONInvalid, despite the fact that the given data is invalid JSON.

If you must validate that you have valid JSON, call IsJSON with your byte string prior to calling GetJSONType. Or call GetJSONTypeStrict.

func GetJSONTypeStrict

func GetJSONTypeStrict(search []byte, start int) string

GetJSONTypeStrict validates the given byte string as JSON and returns the primary JSON type. JSONString, JSONInt, JSONFloat, JSONBool, JSONNull, JSONObject, or JSONArray JSONInvalid ("") denotes a JSON error.

GetJSONTypeStrict WILL perform JSON Validation, and return JSONInvalid if that validation fails. This is slower than GetJSONType due to the extra validation involved.

func Indent added in v1.0.20

func Indent(b []byte) *bytes.Buffer

func IsEmptyArray

func IsEmptyArray(b []byte) bool

IsEmptyArray returns true if the given JSON is an empty array.

func IsEmptyObject

func IsEmptyObject(b []byte) bool

IsEmptyObject returns true if the given JSON is an empty object.

func IsJSON

func IsJSON(b []byte) bool

IsJSON performs validation on a JSON string.

JSON = null

or true or false
or JSONNumber
or JSONString
or JSONObject
or JSONArray

func IsJSONArray

func IsJSONArray(b []byte) bool

IsJSONArray validates a string as a JSON Array.

JSONArray = [ ]

or [ ArrayElements ]

func IsJSONFalse

func IsJSONFalse(b []byte) bool

IsJSONFalse returns true if the byte array is a JSON false value.

func IsJSONNull

func IsJSONNull(b []byte) bool

IsJSONNull returns true if the byte array is a JSON null value.

func IsJSONNumber

func IsJSONNumber(b []byte) bool

IsJSONNumber validates a string as a JSON Number.

JSONNumber = - PositiveNumber

or PositiveNumber

PositiveNumber = DecimalNumber

or DecimalNumber . Digits
or DecimalNumber . Digits ExponentPart
or DecimalNumber ExponentPart

DecimalNumber = 0

or OneToNine Digits

ExponentPart = e Exponent

or E Exponent

Exponent = Digits

or + Digits
or - Digits

Digits = Digit

or Digits Digit

Digit = 0 through 9 OneToNine = 1 through 9

func IsJSONObject

func IsJSONObject(b []byte) bool

IsJSONObject validates a string as a JSON Object.

JSONObject = { }

or { Members }

func IsJSONString

func IsJSONString(b []byte) bool

IsJSONString validates a string as a JSON String.

JSONString = ""

or " StringCharacters "

func IsJSONTrue

func IsJSONTrue(b []byte) bool

IsJSONTrue returns true if the byte array is a JSON true value.

func MergeJSON added in v1.0.7

func MergeJSON(base, patch []byte) ([]byte, error)

MergeJSON merges two JSONObject together and returns the combination. Base and Patch must be type JSONObject. When keys exist in the base but not in the patch, it will be retained. When keys exist in the patch but not in the base, it will be added to the base. JSONArray, JSONString, JSONInt, JSONFloat, JSONNull in the patch will always override the base. JSONObject in the patch will override anything but JSONObject in the base. JSONObject in the patch AND JSONObject in the base will be merged together.

func PanicRecovery

func PanicRecovery(err *error)

PanicRecovery returns a general use Panic Recovery function to capture panics and returns them as errors. A pointer to the error to populate will be passed in via the err parameter. err must be addressable.

usage: defer PanicRecovery(&err)()

func Unmarshal

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

Unmarshal takes a json format byte string and extracts it into the given container.

func UnmarshalStrict

func UnmarshalStrict(raw []byte, v interface{}) (err error)

UnmarshalStrict takes a json format byte string and extracts it into the given container using strict standards for type association.

Types

type Iterator

type Iterator struct {
	// contains filtered or unexported fields
}

Iterator receives a raw JSONArray or JSONObject, and provides an interface for extracting each member item one-by-one.

func NewIterator

func NewIterator(raw []byte) (*Iterator, error)

NewIterator returns a primed Iterator

func (*Iterator) Index

func (i *Iterator) Index(idx int) ([]byte, string, error)

Index moves the internal counter to AFTER the specified member position, and returns the data in that member position. Positions are zero-based, so the first member is Index(0). Note that this means Last() will return the same data as Index(n) when called immediately after Index.

func (*Iterator) Last

func (i *Iterator) Last() ([]byte, string, error)

Last returns the most recently accessed member element in the container, or the first element if never accessed.

func (*Iterator) Next

func (i *Iterator) Next() ([]byte, string, error)

Next returns the next member element in the container.

func (*Iterator) Reset

func (i *Iterator) Reset()

Reset moves the internal pointer to the beginning of the JSON Input.

type JSONReader

type JSONReader struct {
	// Keys holds the list of top-level keys
	Keys []string

	// Type is the JSONType of the top-level data.
	Type string

	// Empty is true if parsing failed or no data was supplied.
	Empty bool

	// StrictStandards directs the extraction functions to be strict with type
	// casting and extractions where applicable.
	StrictStandards bool
	// contains filtered or unexported fields
}

JSONReader Provides utility functions for manipulating json structures.

func ExtractReader

func ExtractReader(search []byte, path string) (*JSONReader, error)

ExtractReader performs an Extract on the given JSON path. The resulting value is returned in the form of a JSONReader primed with the value returned from Extract.

func NewJSONReader

func NewJSONReader(rawData []byte) (reader *JSONReader, err error)

NewJSONReader creates a new JSONReader object, which parses the rawData input and provides access to various accessor functions useful for working with JSONData.

Behavior is undefined when a JSONReader is created via means other than NewJSONReader.

func (*JSONReader) Get

func (jr *JSONReader) Get(key string) *JSONReader

Get retrieves a nested object and returns a JSONReader with the root containing the contents of the delved key.

func (*JSONReader) GetBool

func (jr *JSONReader) GetBool(key string) bool

GetBool retrieves a given key as boolean, if it exists.

func (*JSONReader) GetBoolSlice

func (jr *JSONReader) GetBoolSlice(key string) []bool

GetBoolSlice retrieves a given key as a bool slice, if it exists.

func (*JSONReader) GetByteSlice

func (jr *JSONReader) GetByteSlice(key string) []byte

GetByteSlice returns the given key and all child elements as a byte array.

func (*JSONReader) GetByteSlices

func (jr *JSONReader) GetByteSlices(key string) [][]byte

GetByteSlices retrieves a given key as a slice of byte slices, if it exists.

func (*JSONReader) GetCollection

func (jr *JSONReader) GetCollection(key string) []JSONReader

GetCollection extracts a nested JSONArray and returns a slice of JSONReader, with one JSONReader for each element in the JSONArray.

func (*JSONReader) GetFloat

func (jr *JSONReader) GetFloat(key string) float64

GetFloat retrieves a given key as float64, if it exists.

func (*JSONReader) GetFloatSlice

func (jr *JSONReader) GetFloatSlice(key string) []float64

GetFloatSlice retrieves a given key as a float64 slice, if it exists.

func (*JSONReader) GetInt

func (jr *JSONReader) GetInt(key string) int

GetInt retrieves a given key as an int, if it exists.

func (*JSONReader) GetIntSlice

func (jr *JSONReader) GetIntSlice(key string) []int

GetIntSlice retrieves a given key as a int slice, if it exists.

func (*JSONReader) GetInterface

func (jr *JSONReader) GetInterface(key string) interface{}

GetInterface returns the data given key as an interface{} based on the JSONType of the data.

func (*JSONReader) GetInterfaceSlice

func (jr *JSONReader) GetInterfaceSlice(key string) []interface{}

GetInterfaceSlice returns the given key as an interface{} slice.

func (*JSONReader) GetMapStringInterface

func (jr *JSONReader) GetMapStringInterface(key string) map[string]interface{}

GetMapStringInterface retrieves a given key as a map of string onto interface{}, if said key exists.

func (*JSONReader) GetString

func (jr *JSONReader) GetString(key string) string

GetString retrieves a given key as a string, if it exists.

func (*JSONReader) GetStringSlice

func (jr *JSONReader) GetStringSlice(key string) []string

GetStringSlice retrieves a given key as a string slice, if it exists.

func (*JSONReader) KeyExists

func (jr *JSONReader) KeyExists(key string) bool

KeyExists returns true if a given key exists in the parsed json.

func (*JSONReader) ToBool

func (jr *JSONReader) ToBool() bool

ToBool returns the top-level JSON into an integer.

func (*JSONReader) ToBoolSlice

func (jr *JSONReader) ToBoolSlice() []bool

ToBoolSlice returns all top-level data as a bool slice.

func (*JSONReader) ToByteSlice

func (jr *JSONReader) ToByteSlice() []byte

ToByteSlice returns all top-level data as a byte slice.

func (*JSONReader) ToByteSlices

func (jr *JSONReader) ToByteSlices() [][]byte

ToByteSlices returns all top-level data as a slice of byte slices.

func (*JSONReader) ToFloat

func (jr *JSONReader) ToFloat() float64

ToFloat returns the top-level JSON into a float64.

func (*JSONReader) ToFloatSlice

func (jr *JSONReader) ToFloatSlice() []float64

ToFloatSlice returns all top-level data as a float64 slice.

func (*JSONReader) ToInt

func (jr *JSONReader) ToInt() int

ToInt returns the top-level JSON into an integer.

func (*JSONReader) ToIntSlice

func (jr *JSONReader) ToIntSlice() []int

ToIntSlice returns all top-level data as a int slice.

func (*JSONReader) ToInterface

func (jr *JSONReader) ToInterface() interface{}

ToInterface returns the top-level JSON as an interface{} based on the JSONType of the data.

func (*JSONReader) ToInterfaceSlice

func (jr *JSONReader) ToInterfaceSlice() []interface{}

ToInterfaceSlice returns all top-level data as an interface{} slice.

func (*JSONReader) ToMapStringBool

func (jr *JSONReader) ToMapStringBool() map[string]bool

ToMapStringBool returns all top-level data as map of string onto bool.

func (*JSONReader) ToMapStringBytes

func (jr *JSONReader) ToMapStringBytes() map[string][]byte

ToMapStringBytes returns all top-level data as map of string onto []byte.

func (*JSONReader) ToMapStringFloat

func (jr *JSONReader) ToMapStringFloat() map[string]float64

ToMapStringFloat returns all top-level data as map of string onto float64.

func (*JSONReader) ToMapStringInt

func (jr *JSONReader) ToMapStringInt() map[string]int

ToMapStringInt returns all top-level data as map of string onto int.

func (*JSONReader) ToMapStringInterface

func (jr *JSONReader) ToMapStringInterface() map[string]interface{}

ToMapStringInterface retrieves a given key as a map of string onto interface{}, if said key exists.

func (*JSONReader) ToMapStringString

func (jr *JSONReader) ToMapStringString() map[string]string

ToMapStringString returns all top-level data as map of string onto string.

func (*JSONReader) ToString

func (jr *JSONReader) ToString() string

ToString returns the top-level JSON as a string.

func (*JSONReader) ToStringSlice

func (jr *JSONReader) ToStringSlice() []string

ToStringSlice returns all top-level data as a string slice.

type PostUnmarshaler

type PostUnmarshaler interface {
	PostUnmarshalJSON([]byte, error) error
}

PostUnmarshaler is the interface implemented by types that can perform actions after Unmarshal / UnmarshalJSON has finished. This allows you to inspect the results and make corrections / adjustments / error checking after the unmarshaler has finished its work. An example use case is checking whether a slice is nil after unmarshal.

Errors returned from PostUnmarshalJSON executed by the Unmarshal function (rather than called explicitly) will be ignored, UNLESS that error is included as the parameter to a panic. A panic inside PostUnmarshalJSON will be returned as the error return value from Unmarshal's PanicRecovery functionality.

type StructDescriptor

type StructDescriptor struct {
	Keys         map[string]StructKey
	RequiredKeys []string
	NonEmptyKeys []string

	// KeyMap links alternate names for a field onto a "primary" field.
	KeyMap map[string]string
}

StructDescriptor holds parsed metadata about a given struct.

func (*StructDescriptor) NonEmpty

func (d *StructDescriptor) NonEmpty(key string) bool

NonEmpty returns true if a key is required to be NonEmpty

func (*StructDescriptor) Required

func (d *StructDescriptor) Required(key string) bool

Required returns true if a key is required to exist

type StructKey

type StructKey struct {
	// Type is the type of the struct key.
	Type reflect.Type

	// Kind is the kind of the struct key.
	Kind reflect.Kind

	// Name is the primary name for the given struct key.
	Name string

	// Index is the position in the struct where the given field can be found.
	Index int

	// Path maintains the path we need to traverse through struct keys to resolve embeded keys.
	Path []int
}

StructKey provides information about a single field in a struct

Jump to

Keyboard shortcuts

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