tree

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2022 License: MIT Imports: 8 Imported by: 4

README

Tree

PkgGoDev Report Card

Tree is a simple structure for dealing with dynamic or unknown JSON/YAML structures in Go.

Formats

Go
tree.Map{
	"ID":     tree.ToValue(1),
	"Name":   tree.ToValue("Reds"),
	"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
}
JSON
{
	"ID": 1,
	"Name": "Reds",
	"Colors": ["Crimson", "Red", "Ruby", "Maroon"]
}
YAML
ID: 1
Name: Reds
Colors:
- Crimson
- Red
- Ruby
- Maroon

Marshal and Unmarshal

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/jarxorg/tree"
	"gopkg.in/yaml.v2"
)

func main() {
	group := tree.Map{
		"ID":     tree.ToValue(1),
		"Name":   tree.ToValue("Reds"),
		"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
	}
	j, err := json.Marshal(group)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(j))
	fmt.Println()

	y, err := yaml.Marshal(group)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Print(string(y))
	fmt.Println()

	var n tree.Map
	if err := json.Unmarshal(j, &n); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%#v\n", n)
	fmt.Println()

	r, err := tree.Find(n, ".Colors[1]")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%#v\n", r)
	fmt.Println()

	// Output:
	// {"Colors":["Crimson","Red","Ruby","Maroon"],"ID":1,"Name":"Reds"}
	//
	// Colors:
	// - Crimson
	// - Red
	// - Ruby
	// - Maroon
	// ID: 1
	// Name: Reds
	//
	// tree.Map{"Colors":tree.Array{"Crimson", "Red", "Ruby", "Maroon"}, "ID":1, "Name":"Reds"}
	//
	// "Red"
}

Query

Tree Query Results
.store.book[0] {"category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95}
.store.book[0].price 8.95
.store.book.0.price 8.95
.store.book[:2].price [8.95, 12.99]
.store.book[].author ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"]
.store.book[(.category == "fiction" or .category == "reference") and .price < 10].title ["Sayings of the Century", "Moby Dick"]
.store.book[.authors[0] == "Nigel Rees"].title ["Sayings of the Century"]
Illustrative Object
{
  "store": {
    "book": [{
        "category": "reference",
        "author": "Nigel Rees",
        "authors": ["Nigel Rees"],
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "authors": ["Evelyn Waugh"],
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "authors": ["Herman Melville"],
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "authors": ["J. R. R. Tolkien"],
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

tq - Command line tool

Install
go install github.com/jarxorg/tree/cmd/tq@latest
Usage
tq is a portable command-line JSON/YAML processor.

Usage:
  tq [flags] [query]

Flags:
  -h	help for tq
  -i value
    	input format (json or yaml) (default json)
  -o value
    	output format (json or yaml) (default json)
  -r	output raw strings
  -t string
    	golang text/template string (ignore -o flag)
  -x	expand results

Examples:
  % echo '{"colors": ["red", "green", "blue"]}' | tq '.colors[0]'
  "red"

  % echo '{"users":[{"id":1,"name":"one"},{"id":2,"name":"two"}]}' | tq -x -t '{{.id}}: {{.name}}' '.users'
  1: one
  2: two
for jq user
tq jq
tq '.store.book[0]' jq '.store.book[0]'
tq -x '.store.book' jq '.store.book[]'
tq -x '.store.book[:2].price' jq '.store.book[:2][] | .price'
tq -x '.store.book[.category == "fiction" and .price < 10].title' jq '.store.book[] | select(.category == "fiction" and .price < 10) | .title'
tq -x '.store.book[.authors[0] == "Nigel Rees"].title' jq '.store.book[] | select(.authors[0] == "Nigel Rees") | .title'

Documentation

Index

Examples

Constants

View Source
const (
	TypeArray Type = 1 << (32 - 1 - iota)
	TypeMap
	TypeValue
	TypeStringValue = TypeValue | iota
	TypeBoolValue
	TypeNumberValue
)

These variables are the Node types.

Variables

View Source
var SkipWalk = errors.New("skip")

SkipWalk is used as a return value from WalkFunc to indicate that the node and that children in the call is to be skipped. It is not returned as an error by any function.

Functions

func MarshalJSON

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

MarshalJSON returns the JSON encoding of the specified node.

Example
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/jarxorg/tree"
)

func main() {
	group := tree.Map{
		"ID":     tree.ToValue(1),
		"Name":   tree.ToValue("Reds"),
		"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
	}
	b, err := json.Marshal(group)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(b))

}
Output:

{"Colors":["Crimson","Red","Ruby","Maroon"],"ID":1,"Name":"Reds"}
Example (Combined)
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/jarxorg/tree"
)

func main() {
	type ColorGroup struct {
		ID     int
		Name   string
		Colors tree.Array
	}
	group := ColorGroup{
		ID:     1,
		Name:   "Reds",
		Colors: tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
	}
	b, err := json.Marshal(group)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(b))

}
Output:

{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}

func MarshalYAML

func MarshalYAML(n Node) ([]byte, error)

MarshalYAML returns the YAML encoding of the specified node.

Example
group := tree.Map{
	"ID":     tree.ToValue(1),
	"Name":   tree.ToValue("Reds"),
	"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
}
b, err := yaml.Marshal(group)
if err != nil {
	log.Fatal(err)
}
fmt.Println(string(b))
Output:

Colors:
- Crimson
- Red
- Ruby
- Maroon
ID: 1
Name: Reds

func Walk added in v0.2.0

func Walk(n Node, fn WalkFunc) error

Walk walks the node tree rooted at root, calling fn for each node or that children in the tree, including root.

Types

type And added in v0.4.0

type And []Selector

func (And) Matches added in v0.4.0

func (ss And) Matches(i int, n Node) (bool, error)

type Array

type Array []Node

Array represents an array of Node.

func ToArrayValues added in v0.2.0

func ToArrayValues(vs ...interface{}) Array

ToArrayValues calss ToValues for each provided vs and returns them as an Array.

func (Array) Array

func (n Array) Array() Array

Array returns this node as an Array.

func (Array) Each added in v0.3.0

func (n Array) Each(cb func(key interface{}, n Node) error) error

Each calls the callback function for each Array values.

func (Array) Get added in v0.1.1

func (n Array) Get(key interface{}) Node

Get returns an array value as Node.

func (Array) Map

func (n Array) Map() Map

Map returns nil.

func (Array) Type

func (n Array) Type() Type

Type returns TypeArray.

func (*Array) UnmarshalJSON

func (n *Array) UnmarshalJSON(data []byte) error

UnmarshalJSON is an implementation of json.Unmarshaler.

func (*Array) UnmarshalYAML

func (n *Array) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML is an implementation of yaml.Unmarshaler.

func (Array) Value

func (n Array) Value() Value

Value returns nil.

type ArrayQuery added in v0.2.0

type ArrayQuery int

ArrayQuery is an index of the Array that implements methods of the Query.

func (ArrayQuery) Exec added in v0.2.0

func (q ArrayQuery) Exec(n Node) (Node, error)

type ArrayRangeQuery added in v0.2.0

type ArrayRangeQuery []int

ArrayRangeQuery represents a range of the Array that implements methods of the Query.

func (ArrayRangeQuery) Exec added in v0.2.0

func (q ArrayRangeQuery) Exec(n Node) (Node, error)

type BoolValue

type BoolValue bool

A BoolValue represents a bool value.

func (BoolValue) Array

func (n BoolValue) Array() Array

Array returns nil.

func (BoolValue) Bool

func (n BoolValue) Bool() bool

Bool returns this.

func (BoolValue) Compare added in v0.2.0

func (n BoolValue) Compare(op Operator, v Value) bool

Compare compares n and v.

func (BoolValue) Each added in v0.3.0

func (n BoolValue) Each(cb func(key interface{}, n Node) error) error

Each calls cb(nil, n).

func (BoolValue) Float64

func (n BoolValue) Float64() float64

Float64 returns 0.

func (BoolValue) Get added in v0.1.1

func (n BoolValue) Get(key interface{}) Node

Get returns nil.

func (BoolValue) Int

func (n BoolValue) Int() int

Int returns 0.

func (BoolValue) Int64

func (n BoolValue) Int64() int64

Int64 returns 0.

func (BoolValue) Map

func (n BoolValue) Map() Map

Map returns nil.

func (BoolValue) String

func (n BoolValue) String() string

String returns this as string.

func (BoolValue) Type

func (n BoolValue) Type() Type

Type returns TypeValue.

func (BoolValue) Value

func (n BoolValue) Value() Value

Value returns this.

type Comparator added in v0.2.0

type Comparator struct {
	Left  Query
	Op    Operator
	Right Query
}

Comparator represents a comparable selector.

func (Comparator) Matches added in v0.2.0

func (c Comparator) Matches(i int, n Node) (bool, error)

Matches evaluates left and right using the operator. (eg. .id == 0)

type FilterQuery added in v0.2.0

type FilterQuery []Query

FilterQuery consists of multiple queries that filter the nodes in order.

func (FilterQuery) Exec added in v0.2.0

func (qs FilterQuery) Exec(n Node) (Node, error)

type Map

type Map map[string]Node

Map represents a map of Node.

func (Map) Array

func (n Map) Array() Array

Array returns nil.

func (Map) Each added in v0.3.0

func (n Map) Each(cb func(key interface{}, n Node) error) error

Each calls the callback function for each Map values.

func (Map) Get added in v0.1.1

func (n Map) Get(key interface{}) Node

Get returns an array value as Node.

func (Map) Map

func (n Map) Map() Map

Map returns this node as a Map.

func (Map) Type

func (n Map) Type() Type

Type returns TypeMap.

func (*Map) UnmarshalJSON

func (n *Map) UnmarshalJSON(data []byte) error

UnmarshalJSON is an implementation of json.Unmarshaler.

func (*Map) UnmarshalYAML

func (n *Map) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML is an implementation of yaml.Unmarshaler.

func (Map) Value

func (n Map) Value() Value

Value returns nil.

type MapQuery added in v0.2.0

type MapQuery string

MapQuery is a key of the Map that implements methods of the Query.

func (MapQuery) Exec added in v0.2.0

func (q MapQuery) Exec(n Node) (Node, error)

type Node

type Node interface {
	// Type returns this node type.
	Type() Type
	// Array returns this node as an Array.
	Array() Array
	// Map returns this node as a Map.
	Map() Map
	// Value returns this node as a Value.
	Value() Value
	// Get returns array/map value that matched by the specified key.
	// The key type allows int or string.
	Get(key interface{}) Node
	// Each calls the callback function for each Array|Map values.
	// If the node type is not Array|Map then the callback called once with nil key and self as value.
	Each(cb func(key interface{}, v Node) error) error
}

A Node is an element on the tree.

func DecodeJSON added in v0.2.0

func DecodeJSON(dec *json.Decoder) (Node, error)

DecodeJSON decodes JSON as a node using the provided decoder.

func DecodeYAML added in v0.2.0

func DecodeYAML(dec *yaml.Decoder) (Node, error)

DecodeYAML decodes YAML as a node using the provided decoder.

func Find added in v0.2.0

func Find(n Node, expr string) (Node, error)

Find finds a node from n using the Query.

Example
package main

import (
	"fmt"
	"log"

	"github.com/jarxorg/tree"
)

func main() {
	group := tree.Map{
		"ID":     tree.ToValue(1),
		"Name":   tree.ToValue("Reds"),
		"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
	}

	results, err := tree.Find(group, ".Colors[1]")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%#v\n", results)

}
Output:

"Red"

func ToNode

func ToNode(v interface{}) Node

ToNode converts the specified v to an Node.

func ToValue

func ToValue(v interface{}) Node

ToValue converts the specified v to a Value as Node. Node.Value() returns converted value.

func UnmarshalJSON

func UnmarshalJSON(data []byte) (Node, error)

UnmarshalJSON parses the JSON-encoded data to a Node.

Example
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/jarxorg/tree"
)

func main() {
	data := []byte(`[
  {"Name": "Platypus", "Order": "Monotremata"},
  {"Name": "Quoll",    "Order": "Dasyuromorphia"}
]`)

	var animals tree.Array
	err := json.Unmarshal(data, &animals)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%+v\n", animals)

}
Output:

[map[Name:Platypus Order:Monotremata] map[Name:Quoll Order:Dasyuromorphia]]
Example (Combined)
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/jarxorg/tree"
)

func main() {
	data := []byte(`[
  {"Name": "Platypus", "Order": "Monotremata"},
  {"Name": "Quoll",    "Order": "Dasyuromorphia"}
]`)
	type Animal struct {
		Name  string
		Order tree.StringValue
	}
	var animals []Animal
	err := json.Unmarshal(data, &animals)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%+v\n", animals)

}
Output:

[{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]

func UnmarshalYAML

func UnmarshalYAML(data []byte) (Node, error)

UnmarshalYAML returns the YAML encoding of the specified node.

Example
data := []byte(`---
Colors:
- Crimson
- Red
- Ruby
- Maroon
ID: 1
Name: Reds
`)

var group tree.Map
if err := yaml.Unmarshal(data, &group); err != nil {
	log.Fatal(err)
}
fmt.Printf("%+v\n", group)
Output:

map[Colors:[Crimson Red Ruby Maroon] ID:1 Name:Reds]

type NumberValue

type NumberValue float64

A NumberValue represents an number value.

func (NumberValue) Array

func (n NumberValue) Array() Array

Array returns nil.

func (NumberValue) Bool

func (n NumberValue) Bool() bool

Bool returns false.

func (NumberValue) Compare added in v0.2.0

func (n NumberValue) Compare(op Operator, v Value) bool

Compare compares n and v.

func (NumberValue) Each added in v0.3.0

func (n NumberValue) Each(cb func(key interface{}, n Node) error) error

Each calls cb(nil, n).

func (NumberValue) Float64

func (n NumberValue) Float64() float64

Float64 returns float64(n).

func (NumberValue) Get added in v0.1.1

func (n NumberValue) Get(key interface{}) Node

Get returns nil.

func (NumberValue) Int

func (n NumberValue) Int() int

Int returns int(n).

func (NumberValue) Int64

func (n NumberValue) Int64() int64

Int64 returns int64(n).

func (NumberValue) Map

func (n NumberValue) Map() Map

Map returns nil.

func (NumberValue) String

func (n NumberValue) String() string

String returns this as string using strconv.FormatFloat(float64(n), 'f', -1, 64).

func (NumberValue) Type

func (n NumberValue) Type() Type

Type returns TypeValue.

func (NumberValue) Value

func (n NumberValue) Value() Value

Value returns this.

type Operator added in v0.2.0

type Operator string

Operator represents an operator.

var (
	// EQ is `==`.
	EQ Operator = "=="
	// GT is `>`.
	GT Operator = ">"
	// GE is `>=`.
	GE Operator = ">="
	// LT is `<`.
	LT Operator = "<"
	// LE is `<=`.
	LE Operator = "<="
)

type Or added in v0.4.0

type Or []Selector

func (Or) Matches added in v0.4.0

func (ss Or) Matches(i int, n Node) (bool, error)

type Query added in v0.2.0

type Query interface {
	Exec(n Node) (Node, error)
}

Query is an interface that defines the methods to query a node.

var NopQuery Query = nopQuery{}

NopQuery is a query that implements no-op Exec method.

func ParseQuery added in v0.2.0

func ParseQuery(expr string) (Query, error)

ParseQuery parses the provided expr to a Query. See https://github.com/jarxorg/tree#Query

type SelectQuery added in v0.2.0

type SelectQuery struct {
	Selector
}

SelectQuery returns nodes that matched by selectors.

func (SelectQuery) Exec added in v0.2.0

func (q SelectQuery) Exec(n Node) (Node, error)

type Selector added in v0.2.0

type Selector interface {
	Matches(i int, n Node) (bool, error)
}

Selector checks if a node is eligible for selection.

type StringValue

type StringValue string

A StringValue represents a string value.

func (StringValue) Array

func (n StringValue) Array() Array

Array returns nil.

func (StringValue) Bool

func (n StringValue) Bool() bool

Bool returns false.

func (StringValue) Compare added in v0.2.0

func (n StringValue) Compare(op Operator, v Value) bool

Compare compares n and v.

func (StringValue) Each added in v0.3.0

func (n StringValue) Each(cb func(key interface{}, n Node) error) error

Each calls cb(nil, n).

func (StringValue) Float64

func (n StringValue) Float64() float64

Float64 returns 0.

func (StringValue) Get added in v0.1.1

func (n StringValue) Get(key interface{}) Node

Get returns nil.

func (StringValue) Int

func (n StringValue) Int() int

Int returns 0.

func (StringValue) Int64

func (n StringValue) Int64() int64

Int64 returns 0.

func (StringValue) Map

func (n StringValue) Map() Map

Map returns nil.

func (StringValue) String

func (n StringValue) String() string

String returns this as string.

func (StringValue) Type

func (n StringValue) Type() Type

Type returns TypeValue.

func (StringValue) Value

func (n StringValue) Value() Value

Value returns this.

type Type

type Type int

Type represents the Node type.

func (Type) IsArray

func (t Type) IsArray() bool

IsArray returns t == TypeArray.

func (Type) IsBoolValue

func (t Type) IsBoolValue() bool

IsBoolValue returns t == TypeBoolValue.

func (Type) IsMap

func (t Type) IsMap() bool

IsMap returns t == TypeMap.

func (Type) IsNumberValue

func (t Type) IsNumberValue() bool

IsNumberValue returns t == TypeNumberValue.

func (Type) IsStringValue

func (t Type) IsStringValue() bool

IsStringValue returns t == TypeStringValue.

func (Type) IsValue

func (t Type) IsValue() bool

IsValue returns true if t is TypeStringValue or TypeBoolValue or TypeNumberValue.

type Value

type Value interface {
	Node
	String() string
	Bool() bool
	Int() int
	Int64() int64
	Float64() float64
	Compare(op Operator, v Value) bool
}

Value provides the accessor of primitive value.

type ValueQuery added in v0.2.0

type ValueQuery struct {
	Node
}

ValueQuery is a query that returns the constant value.

func (ValueQuery) Exec added in v0.2.0

func (q ValueQuery) Exec(n Node) (Node, error)

Exec returns the constant value.

type WalkFunc added in v0.2.0

type WalkFunc func(n Node, keys []interface{}) error

WalkFunc is the type of the function called by Walk to visit each nodes.

The keys argument contains that parent keys and the node key that type is int (array index) or string (map key).

Directories

Path Synopsis
cmd
tq command

Jump to

Keyboard shortcuts

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