jnode

package module
v0.1.11 Latest Latest
Warning

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

Go to latest
Published: Sep 10, 2020 License: Apache-2.0 Imports: 6 Imported by: 38

README

go-jnode

GoDoc GoReport

go-jnode is a Go module that makes using generic JSON structures easy. Its API is modeled on Java's jackson tree model.

Go's builtin generic JSON object uses map[string]interface{} for objects, []interface{} for arrays, and string, bool, float64 for everything else. However, using these generic interfaces safely is awkward and verbose.

go-jnode makes things a little easier:

  • Create a *jnode.Node with any of the factory methods e.g. jnode.NewObjectNode() or jnode.FromJSON()
  • Use chained n.Path(field) or n.Get(index) calls to navigate an object.
  • Use n.Entries() to iterate over maps, and n.Elements() to iterate over arrays.
  • Use n.AsText() to get a text value. (Or n.AsBool(), n.AsInt() etc)
  • Navigation is safe - if the object doesn't have a field or an array doesn't have an index a single MissingNode is returned, for which n.IsMissing() returns true. (The text value of a missing node is empty.)

To install:

go get github.com/soluble-ai/go-jnode

Short example:

import "github.com/soluble-ai/go-jnode"

func example() {
  n := jnode.NewObjectNode().Put("greeting", "hello").Put("subject", "world")

  fmt.Printf("%v\n", n)                     // {"greeting":"hello","subject":"world"}
  fmt.Println(n.Path("greeting").AsText())  // greeting
  fmt.Println(n.Path("not-there").AsText()) // <empty-string>

  n.PutArray("list").Append(1).Append(2)    // adds an Array
  fmt.Println(n.Path("list").Get(1))        // 2

  // can also add slices, which get flattened
  n.Path("list").Append([]string{ "hello", "world" })

  // iteration: use Elements() for arrays, Entries() for maps
  for _, e := range n.Path("list").Elements() {
    fmt.Println(e.AsText());    // "hello" followed by "world"
  }

  // construct from a string
  m, _ := jnode.FromJSON(`{"code":200,"message":"howdy"})`)
  fmt.Println(m.Path("code").AsInt())       // 200
}

Documentation

Overview

The jnode package handles generic JSON documents building on the support provided by Go's "encoding/json".

The API is loosely based on the Java's https://github.com/FasterXML/jackson-databind.

Creating Node's

The Node type represents a generic JSON node (e.g. text, bool, null, int, float, array, or object.) Here's some ways to create a Node:

t := jnode.NewNode("hello")
i := jnode.NewNode(10)

// return values chain
o := jnode.NewObject().Put("greeting", "hello").Put("subject", "world")
a := jnode.NewArray().Append(1).Append(2).Append(3)

o.PutArray("list").Append(true).Append(100.0)
o.PutObject("struct").Put("one", 1)

// Put/Append can take other nodes or simple types
a.Append(jnode.NewObject().Put("two", 2))

// Can also build from JSON
n, _ := json.FromJSON([]byte(`{"three": 3}`)

The Put methods accept simple types, slices, maps and other Node's. For complex types the argument will be copied, and it may be modified (see implementation note below.)

Navigation

For Object Node's, use Path:

o.Path("greeting").AsText()         // "hello"

o.Path("x").Path("y").AsText()      // "", missing paths return jnode.MissingNode

jnode.NewNode("hello").Path("foo")  // also returns jnode.MissingNode

All elements of an Object can be accessed via Entries(). All elements of an Array Node can be accessed via Elements(). Both methods return empty maps or slices if the Node is not an Object or Array respectively.

JSON Marshal

A Node's String() method returns JSON:

o := jnode.NewObject().put("one", 1)
fmt.Println(o)  // {"one":1}

Note that because jnode is building on the generic JSON support in Go, the order of fields in an Object is unpredictable.

Implementation Note

A Node holds an interface{}, which stores the unwrapped Go value. (A Node does not contain another Node, only the basic generic JSON values.) For Array values ([]interface{}) the Node holds a pointer to the slice instead of the slice directly. (This is necessary because Append creates new slices.)

For this reason, when jnode accepts an []interface{} or map[string]interface{} (via Put, Append, FromSlice, or FromMap) it will rewrite any slices to pointers to slices.

During JSON marshalling the code walks through the value replacing pointers to slices with slices, then undoing the replacement afterwards. Likewise, during unmarshalling the code walks through the value replacing slices with pointers to the slices.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Node

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

Node represents a JSON value (text, bool, numeric, object, or array.)

var MissingNode *Node = &Node{""}

MissingNode represents a missing node. Path() will return a MissingNode if the field is not found.

var NullNode *Node = &Node{}

NullNode represents the nil (json null) value.

func FromFlatString added in v0.1.7

func FromFlatString(s string) (*Node, error)

FromFlatString converts a string into an object Node. It accepts a string in the form:

field1=value1,field2=value2,....
field1={subobj_field1=value1,...}
field1=[list_value1,list_value2]

The first form sets the fields and values of the object. The second form sets the fields and values of a nested object. The final form sets the values of an array.

func FromJSON

func FromJSON(data []byte) (*Node, error)

FromJSON creates a Node from JSON

func FromMap added in v0.1.4

func FromMap(value map[string]interface{}) *Node

FromMap creates a Node from a generic map. The map may be modified (see implementation note.)

func FromSlice added in v0.1.9

func FromSlice(slice interface{}) *Node

FromSlice creates an array Node from a slice.

func NewArrayNode

func NewArrayNode() *Node

NewArrayNode creates a Node that wraps a []interface{}. Array nodes corresponds to JSON arrays.

func NewNode

func NewNode(value interface{}) *Node

NewNode creates a Node from a simple value (nil, string, bool int, int8, int16, int32, int64, float32, or float64.)

func NewObjectNode

func NewObjectNode() *Node

NewObjectNode creates a Node that wraps a map[string]interface{}. Object nodes correspond to JSON objects.

func (*Node) Append

func (n *Node) Append(value interface{}) *Node

Append adds a new element to an Array Node and returns the Array. Panics if the Node is not an Array. The element may itself be a slice, in which case the slice is flattened into the array.

func (*Node) AppendE

func (n *Node) AppendE(value interface{}) error

AppendE adds a new element to an Array Node and returns the Array. Returns an error if the Node is not an Array.

func (*Node) AppendObject added in v0.1.9

func (n *Node) AppendObject() *Node

AppendObject adds a new ObjectNode to an array node, and returns the new object node. Panics if the node is not an array node.

func (*Node) AppendObjectE added in v0.1.9

func (n *Node) AppendObjectE() (*Node, error)

AppendObjectE adds a new ObjectNode to an array node and returns the new array node. Returns an error if this node is not an array node.

func (*Node) AsBinary

func (n *Node) AsBinary() ([]byte, error)

AsBinary returns the binary value of a Node. If the Node is string, it attempts to base64 decode it.

func (*Node) AsBool

func (n *Node) AsBool() bool

AsBool returns the boolean value of a Node. For strings, returns true if the string is equal to "true" (ignoring case). For numeric types, returns true if AsInt() != 0.

func (*Node) AsFloat

func (n *Node) AsFloat() float64

AsFloat returns the Node as a float64. For string values it parses the string with strconv.ParseFloat or returns 0. For bool returns 0 or 1. Otherwise returns 0.

func (*Node) AsInt

func (n *Node) AsInt() int

AsInt returns the value of a Node as an int. For a String, returns the value of strconv.Atoi or 0. For bool returns 0 or 1. Otherwise returns 0.

func (*Node) AsText

func (n *Node) AsText() string

AsText returns the text of a Node

func (*Node) Elements

func (n *Node) Elements() []*Node

Elements returns the elements of an Array Node (or an empty slice if the Node is not an Array.)

func (*Node) Entries

func (n *Node) Entries() map[string]*Node

Entries returns the entries of an Object Node (or an empty map if the Node is not an Object.)

func (*Node) Get

func (n *Node) Get(i int) *Node

Get returns the i-th element of an Array Node. If the Node is not an Array, or the index is beyond the bounds of the Array, MissingNode is returned

func (*Node) GetType

func (n *Node) GetType() NodeType

GetType returns the type of a Node

func (*Node) IsArray

func (n *Node) IsArray() bool

IsArray returns true if the Node is an Array

func (*Node) IsContainer added in v0.1.4

func (n *Node) IsContainer() bool

IsContainer returns true if the Node is an Object or Array

func (*Node) IsMissing

func (n *Node) IsMissing() bool

IsMissing returns true if the Node is missing

func (*Node) IsNull

func (n *Node) IsNull() bool

IsNull returns true if the Node is the NullNode

func (*Node) IsNumber added in v0.1.11

func (n *Node) IsNumber() bool

IsNumber returns true fi the Node is a number

func (*Node) IsObject

func (n *Node) IsObject() bool

IsObject returns true if the Node is an Object

func (*Node) MarshalJSON

func (n *Node) MarshalJSON() ([]byte, error)

MarshalJSON is the custom JSON marshaller for a Node

func (*Node) Path

func (n *Node) Path(name string) *Node

Path returns the value of a field of an Object Node. Returns MissingNode if the Node is not an Object or the field is not present

func (*Node) Put

func (n *Node) Put(name string, value interface{}) *Node

Put sets the value of a field in an Object Node. Returns the Node (for chaining). Panics if the Node is not an Object.

func (*Node) PutArray

func (n *Node) PutArray(name string) *Node

PutArray sets a field in an Object Node to a new Array Node, and returns the new Array Node. Panics if the Node is not an Object.

func (*Node) PutArrayE

func (n *Node) PutArrayE(name string) (*Node, error)

PutArrayE sets a field in an Object Node to a new Array Node, and returns the new Array Node. Returns an error if the Node is not an Object.

func (*Node) PutE

func (n *Node) PutE(name string, value interface{}) (*Node, error)

PutE sets the value of a field in an Object Node, or returns an error if the Node is not an Object.

func (*Node) PutObject

func (n *Node) PutObject(name string) *Node

PutObject sets the value of a field to a new Object Node and returns the new Object Node. Panics if the Node is not an Object.

func (*Node) PutObjectE

func (n *Node) PutObjectE(name string) (*Node, error)

PutObjectE sets the value of a field to a new Object Node and returns the new Object Node. Returns an error if the Node is not an Object.

func (*Node) Remove added in v0.1.10

func (n *Node) Remove(name string) *Node

Remove removes a field of an Object Node. Remove is a no-op if the node is not an object, or doesn't contain the field.

func (*Node) Set added in v0.1.4

func (n *Node) Set(i int, value interface{}) *Node

Set sets the i'th element of an array to a value. Panics if i is out of bounds, or the value is invalid.

func (*Node) SetE added in v0.1.4

func (n *Node) SetE(i int, value interface{}) error

SetE sets the i'th element of an array node to a value.

func (*Node) Size

func (n *Node) Size() int

Size returns the length of an Array, the number of fields in an Object, or 0 otherwise.

func (*Node) String

func (n *Node) String() string

String returns the Node formatted as JSON

func (*Node) ToMap added in v0.1.10

func (n *Node) ToMap() map[string]interface{}

ToMap returns this node as a generic map[string]interface{} via a cast. Panics if this node is not an Object.

func (*Node) UnmarshalJSON

func (n *Node) UnmarshalJSON(b []byte) error

UnmarshalJSON is the custom JSON unmarshaller for a Node

func (*Node) Unwrap added in v0.1.2

func (n *Node) Unwrap() interface{}

Unwrap returns the generic value from a Node

type NodeType added in v0.1.3

type NodeType int
const (
	Unknown NodeType = iota
	Text
	Number
	Bool
	Binary
	Array
	Object
	Missing
	Null
)

func (NodeType) String added in v0.1.3

func (i NodeType) String() string

Jump to

Keyboard shortcuts

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