jsonry

package module
v1.1.4 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2022 License: Apache-2.0 Imports: 9 Imported by: 18

README

test go.dev reference

JSONry

A Go library and notation for converting between a Go struct and JSON.

import "code.cloudfoundry.org/jsonry"

s := struct {
  GUID string `jsonry:"relationships.space.data.guid"`
}{
  GUID: "267758c0-985b-11ea-b9ac-48bf6bec2d78",
}

json, _ := jsonry.Marshal(s)
fmt.Println(string(json))

Will generate the following JSON:

{
  "relationships": {
    "space": {
      "data": {
        "guid": "267758c0-985b-11ea-b9ac-48bf6bec2d78"
      }
    }
  }
}

The operation is reversible using Unmarshal(). The key advantage is that nested JSON can be generated and parsed without the need to create intermediate Go structures. Check out the documentation for details.

JSONry started life in the Cloud Foundry CLI project. It has been extracted so that it can be used in other projects too.

More information:

Documentation

Overview

Package jsonry exists to make is easier to marshal and unmarshal nested JSON into Go structures. For example:

{
  "relationships": {
    "space": {
      "data": {
        "guid": "267758c0-985b-11ea-b9ac-48bf6bec2d78"
      }
    }
  }
}

Can be marshaled and unmarshaled using the Go struct:

type s struct { GUID string `jsonry:"relationships.space.data.guid"` }

There is no need to create intermediate structures as would be required with the standard Go JSON parser.

JSONry uses the standard Go parser under the covers. JSONry is a trade-off that delivers usability in exchange for performance.

JSONry uses struct tags to specify locations in the JSON document.

When there is neither a "jsonry" or "json" struct tag, the JSON object key name will be the same as the struct field name. For example:

Go: s := struct { Foo string }{Foo: "value"}
JSON: {"Foo": "value"}

When there is a "json" struct tag, it will be interpreted in the same way as the standard Go JSON parser would interpret it. For example:

Go: s := struct { Foo string `json:"bar"` }{Foo: "value"}
JSON: {"bar": "value"}

When there is a "jsonry" struct tag, in addition to working like the "json" tag, it may also contain "." (period) to denote a nesting hierarchy. For example:

Go: s := struct { Foo string `jsonry:"foo.bar"` }{Foo: "value"}
JSON: {"foo": {"bar": "value"} }

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

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

Marshal converts the specified Go struct into JSON. The input must be a struct or a pointer to a struct. Where a field is optional, the suffix ",omitempty" can be specified. This will mean that the field will be omitted from the JSON output if it is a nil pointer or has zero value for the type. When a field is a slice or an array, a single list hint "[]" may be specified in the JSONry path so that the array is created at the correct position in the JSON output.

If a type implements the json.Marshaler interface, then the MarshalJSON() method will be called.

If a type implements the jsonry.Omissible interface, then the OmitJSONry() method will be used to to determine whether or not to marshal the field, overriding any `,omitempty` tags.

The field type can be string, bool, int*, uint*, float*, map, slice, array or struct. JSONry is recursive.

Example
package main

import (
	"fmt"

	"code.cloudfoundry.org/jsonry"
)

func main() {
	s := struct {
		A    string
		B    string `json:"bee,omitempty"`
		GUID string `jsonry:"relationships.space.data.guid"`
		IDs  []int  `jsonry:"data.entries[].id"`
	}{
		A:    "foo",
		B:    "",
		GUID: "267758c0-985b-11ea-b9ac-48bf6bec2d78",
		IDs:  []int{1, 2, 3, 4, 5},
	}

	json, err := jsonry.Marshal(s)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(json))
}
Output:

{"A":"foo","data":{"entries":[{"id":1},{"id":2},{"id":3},{"id":4},{"id":5}]},"relationships":{"space":{"data":{"guid":"267758c0-985b-11ea-b9ac-48bf6bec2d78"}}}}
Example (Recursive)
package main

import (
	"fmt"

	"code.cloudfoundry.org/jsonry"
)

func main() {
	type s struct {
		A string `jsonry:"f"`
	}
	type t struct {
		B []s `jsonry:"d[].e"`
	}
	type u struct {
		C []t `jsonry:"a.b[].c"`
	}

	data := u{C: []t{{B: []s{{A: "foo"}, {"bar"}}}, {B: []s{{A: "baz"}, {"quz"}}}}}

	json, err := jsonry.Marshal(data)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(json))
}
Output:

{"a":{"b":[{"c":{"d":[{"e":{"f":"foo"}},{"e":{"f":"bar"}}]}},{"c":{"d":[{"e":{"f":"baz"}},{"e":{"f":"quz"}}]}}]}}

func Unmarshal

func Unmarshal(data []byte, receiver interface{}) error

Unmarshal parses the specified JSON into the specified Go struct receiver. The receiver must be a pointer to a Go struct containing only fields of the type: string, bool, int*, uint*, float*, map, slice or struct. JSONry is recursive.

If a field implements the json.Unmarshaler interface, then the UnmarshalJSON() method will be called.

Example
package main

import (
	"fmt"

	"code.cloudfoundry.org/jsonry"
)

func main() {
	json := `
    {
      "A": "foo",
      "bee": "bar",
      "data": {
        "entries": [
          {"id": 1},
          {"id": 2},
          {"id": 3},
          {"id": 4},
          {"id": 5}
        ]
      },
      "relationships": {
        "space": {
          "data": {
            "guid":"267758c0-985b-11ea-b9ac-48bf6bec2d78"}
          }
        }
      }
    }`

	var s struct {
		A    string
		B    string `json:"bee"`
		GUID string `jsonry:"relationships.space.data.guid"`
		IDs  []int  `jsonry:"data.entries.id"`
	}

	if err := jsonry.Unmarshal([]byte(json), &s); err != nil {
		panic(err)
	}

	fmt.Printf("A: %+v\nB: %+v\nGUID: %+v\nIDs: %+v\n", s.A, s.B, s.GUID, s.IDs)
}
Output:

A: foo
B: bar
GUID: 267758c0-985b-11ea-b9ac-48bf6bec2d78
IDs: [1 2 3 4 5]

Types

type Omissible added in v1.1.0

type Omissible interface {
	OmitJSONry() bool
}

Omissible is the interface implemented by types that indicate whether they should be omitted when being marshaled. It allows for more custom control than the `omitempty` tag. This interface overrides any `omitempty` behavior, and it is not necessary to specify `omitempty` with an Omissible type.

Directories

Path Synopsis
internal
errorcontext
Package errorcontext represents a marshalling or unmarshalling call stack for use in error messages
Package errorcontext represents a marshalling or unmarshalling call stack for use in error messages
path
Package path represents a notation for accessing elements in JSON
Package path represents a notation for accessing elements in JSON
tree
Package tree is a Go representation of a JSON object
Package tree is a Go representation of a JSON object

Jump to

Keyboard shortcuts

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