gojq

package module
v0.12.6 Latest Latest
Warning

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

Go to latest
Published: Dec 1, 2021 License: MIT Imports: 20 Imported by: 472

README

gojq

CI Status Go Report Card MIT License release pkg.go.dev

Pure Go implementation of jq

This is an implementation of jq command written in Go language. You can also embed gojq as a library to your Go products.

Usage

 $ echo '{"foo": 128}' | gojq '.foo'
128
 $ echo '{"a": {"b": 42}}' | gojq '.a.b'
42
 $ echo '{"id": "sample", "10": {"b": 42}}' | gojq '{(.id): .["10"].b}'
{
  "sample": 42
}
 $ echo '[{"id":1},{"id":2},{"id":3}]' | gojq '.[] | .id'
1
2
3
 $ echo '{"a":1,"b":2}' | gojq '.a += 1 | .b *= 2'
{
  "a": 2,
  "b": 4
}
 $ echo '{"a":1} [2] 3' | gojq '. as {$a} ?// [$a] ?// $a | $a'
1
2
3
 $ echo '{"foo": 4722366482869645213696}' | gojq .foo
4722366482869645213696  # keeps the precision of large numbers
 $ gojq -n 'def fact($n): if $n < 1 then 1 else $n * fact($n - 1) end; fact(50)'
30414093201713378043612608166064768844377641568960512000000000000 # arbitrary-precision integer calculation

Nice error messages.

 $ echo '[1,2,3]' | gojq '.foo & .bar'
gojq: invalid query: .foo & .bar
    .foo & .bar
         ^  unexpected token "&"
 $ echo '{"foo": { bar: [] } }' | gojq '.'
gojq: invalid json: <stdin>
    {"foo": { bar: [] } }
              ^  invalid character 'b' looking for beginning of object key string

Installation

Homebrew
brew install gojq
Zero Install
0install add gojq https://apps.0install.net/utils/gojq.xml
Build from source
go install github.com/itchyny/gojq/cmd/gojq@latest
Docker
docker run -i --rm itchyny/gojq
docker run -i --rm ghcr.io/itchyny/gojq

Difference to jq

  • gojq is purely implemented with Go language and is completely portable. jq depends on the C standard library so the availability of math functions depends on the library. jq also depends on the regular expression library and it makes build scripts complex.
  • gojq implements nice error messages for invalid query and JSON input. The error message of jq is sometimes difficult to tell where to fix the query.
  • gojq does not keep the order of object keys. I understand this might cause problems for some scripts but basically, we should not rely on the order of object keys. Due to this limitation, gojq does not have keys_unsorted function and --sort-keys (-S) option. I would implement when ordered map is implemented in the standard library of Go but I'm less motivated. Also, gojq assumes only valid JSON input while jq deals with some JSON extensions; NaN, Infinity and [000].
  • gojq supports arbitrary-precision integer calculation while jq does not. This is important to keep the precision of numeric IDs or nanosecond values. You can also use gojq to solve some mathematical problems which require big integers. Note that mathematical functions convert integers to floating-point numbers; only addition, subtraction, multiplication, modulo operation, and division (when divisible) keep integer precisions. When you want to calculate floor division of big integers, use def intdiv($x; $y): ($x - $x % $y) / $y;, instead of $x / $y.
  • gojq fixes various bugs of jq. gojq correctly deletes elements of arrays by |= empty (jq#2051). gojq fixes try/catch handling (jq#1859, jq#1885, jq#2140). gojq fixes nth/2 to output nothing when the count is equal to or larger than the stream size (jq#1867). gojq consistently counts by characters (not by bytes) in index, rindex, and indices functions; "12345" | .[index("3"):] results in "345" (jq#1430, jq#1624). gojq accepts indexing query .e0 (jq#1526, jq#1651), and allows gsub to handle patterns including "^" (jq#2148). gojq improves variable lexer to allow using keywords for variable names, especially in binding patterns, also disallows spaces after $ (jq#526). gojq fixes handling files with no newline characters at the end (jq#2374).
  • gojq implements @uri to escape all the reserved characters defined in RFC 3986, Sec. 2.2 (jq#1506), and fixes @base64d to allow binary string as the decoded string (jq#1931). gojq improves time formatting and parsing, deals with %f in strftime and strptime (jq#1409), parses timezone offsets with fromdate and fromdateiso8601 (jq#1053), supports timezone name/offset with %Z/%z in strptime (jq#929, jq#2195), and looks up correct timezone during daylight saving time on formatting with %Z (jq#1912).
  • gojq does not support some functions intentionally; get_jq_origin, get_prog_origin, get_search_list (unstable, not listed in jq document), input_line_number, $__loc__ (performance issue), recurse_down (deprecated in jq). gojq does not support some flags; --ascii-output, -a (performance issue), --seq (not used commonly), --sort-keys, -S (sorts by default because map[string]interface{} does not keep the order), --unbuffered. gojq normalizes floating-point numbers to fit to double-precision (64-bit) floating-point numbers. gojq does not support some regular expression flags (regular expression engine differences). gojq does not support BOM (encoding/json does not support this).
  • gojq supports reading from YAML input (--yaml-input) while jq does not. gojq also supports YAML output (--yaml-output).
Color configuration

The gojq command automatically disables coloring output when the output is not a tty. To force coloring output, specify --color-output (-C) option. When NO_COLOR environment variable is present or --monochrome-output (-M) option is specified, gojq disables coloring output.

Use GOJQ_COLORS environment variable to configure individual colors. The variable is a colon-separated list of ANSI escape sequences of null, false, true, numbers, strings, object keys, arrays, and objects. The default configuration is 90:33:33:36:32:34;1.

Usage as a library

You can use the gojq parser and interpreter from your Go products.

package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse(".foo | ..")
	if err != nil {
		log.Fatalln(err)
	}
	input := map[string]interface{}{"foo": []interface{}{1, 2, 3}}
	iter := query.Run(input) // or query.RunWithContext
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}
}
  • Firstly, use gojq.Parse(string) (*Query, error) to get the query from a string.
  • Secondly, get the result iterator
    • using query.Run or query.RunWithContext
    • or alternatively, compile the query using gojq.Compile and then code.Run or code.RunWithContext. You can reuse the *Code against multiple inputs to avoid compilation of the same query.
    • In either case, you cannot use custom type values as the query input. The type should be []interface{} for an array and map[string]interface{} for a map (just like decoded to an interface{} using the encoding/json package). You can't use []int or map[string]string, for example. If you want to query your custom struct, marshal to JSON, unmarshal to interface{} and use it as the query input.
  • Thirdly, iterate through the results using iter.Next() (interface{}, bool). The iterator can emit an error so make sure to handle it. The method returns true with results, and false when the iterator terminates.
    • The return type is not (interface{}, error) because iterators can emit multiple errors and you can continue after an error. It is difficult for the iterator to tell the termination in this situation.
    • Note that the result iterator may emit infinite number of values; repeat(0) and range(infinite). It may stuck with no output value; def f: f; f. Use RunWithContext when you want to limit the execution time.

gojq.Compile allows to configure the following compiler options.

  • gojq.WithModuleLoader allows to load modules. By default, the module feature is disabled. If you want to load modules from the file system, use gojq.NewModuleLoader.
  • gojq.WithEnvironLoader allows to configure the environment variables referenced by env and $ENV. By default, OS environment variables are not accessible due to security reasons. You can use gojq.WithEnvironLoader(os.Environ) if you want.
  • gojq.WithVariables allows to configure the variables which can be used in the query. Pass the values of the variables to code.Run in the same order.
  • gojq.WithFunction allows to add a custom internal function. An internal function can return a single value (which can be an error) each invocation. To add a jq function (which may include a comma operator to emit multiple values, empty function, accept a filter for its argument, or call another built-in function), use LoadInitModules of the module loader.
  • gojq.WithIterFunction allows to add a custom iterator function. An iterator function returns an iterator to emit multiple values. You cannot define both iterator and non-iterator functions of the same name (with possibly different arities). You can use gojq.NewIter to convert values or an error to a gojq.Iter.
  • gojq.WithInputIter allows to use input and inputs functions. By default, these functions are disabled.

Bug Tracker

Report bug at Issues・itchyny/gojq - GitHub.

Author

itchyny (https://github.com/itchyny)

License

This software is released under the MIT License, see LICENSE.

Documentation

Overview

Package gojq provides the parser and interpreter of gojq.

Please refer to https://github.com/itchyny/gojq#usage-as-a-library for introduction of the usage as a library.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal added in v0.12.0

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

Marshal returns the jq-flavored JSON encoding of v.

This method only accepts limited types (nil, bool, int, float64, *big.Int, string, []interface{} and map[string]interface{}) because these are the possible types a gojq iterator can emit. This method marshals NaN to null, truncates infinities to (+|-) math.MaxFloat64, uses \b and \f in strings, and does not escape '<' and '>' for embedding in HTML. These behaviors are based on the marshaler of jq command and different from Go standard library method json.Marshal.

Types

type Array

type Array struct {
	Query *Query
}

Array ...

func (*Array) String added in v0.4.0

func (e *Array) String() string

type Bind added in v0.5.0

type Bind struct {
	Patterns []*Pattern
	Body     *Query
}

Bind ...

func (*Bind) String added in v0.5.0

func (e *Bind) String() string

type Code added in v0.8.0

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

Code is a compiled jq query.

func Compile added in v0.8.0

func Compile(q *Query, options ...CompilerOption) (*Code, error)

Compile compiles a query.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse(".[] | .foo")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(query)
	if err != nil {
		log.Fatalln(err)
	}
	iter := code.Run([]interface{}{
		nil,
		"string",
		42,
		[]interface{}{"foo"},
		map[string]interface{}{"foo": 42},
	})
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			fmt.Println(err)
			continue
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

<nil>
expected an object but got: string ("string")
expected an object but got: number (42)
expected an object but got: array (["foo"])
42

func (*Code) Run added in v0.8.0

func (c *Code) Run(v interface{}, values ...interface{}) Iter

Run runs the code with the variable values (which should be in the same order as the given variables using WithVariables) and returns a result iterator.

It is safe to call this method of a *Code in multiple goroutines.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse(".foo")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(query)
	if err != nil {
		log.Fatalln(err)
	}
	input := map[string]interface{}{"foo": 42}
	iter := code.Run(input)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

42

func (*Code) RunWithContext added in v0.8.0

func (c *Code) RunWithContext(ctx context.Context, v interface{}, values ...interface{}) Iter

RunWithContext runs the code with context.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse("def f: f; f, f")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(query)
	if err != nil {
		log.Fatalln(err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()
	iter := code.RunWithContext(ctx, nil)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			fmt.Println(err)
			continue
		}
		_ = v
	}

}
Output:

context deadline exceeded

type CompilerOption added in v0.8.0

type CompilerOption func(*compiler)

CompilerOption is a compiler option.

func WithEnvironLoader added in v0.9.0

func WithEnvironLoader(environLoader func() []string) CompilerOption

WithEnvironLoader is a compiler option for environment variables loader. The OS environment variables are not accessible by default due to security reason. You can pass os.Environ if you allow to access it.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse("env | keys[]")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(
		query,
		gojq.WithEnvironLoader(func() []string {
			return []string{"foo=42", "bar=128"}
		}),
	)
	if err != nil {
		log.Fatalln(err)
	}
	iter := code.Run(nil)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

"bar"
"foo"

func WithFunction added in v0.12.0

func WithFunction(name string, minarity, maxarity int,
	f func(interface{}, []interface{}) interface{}) CompilerOption

WithFunction is a compiler option for adding a custom internal function. Specify the minimum and maximum count of the function arguments. These values should satisfy 0 <= minarity <= maxarity <= 30, otherwise panics. On handling numbers, you should take account to int, float64 and *big.Int. These are the number types you are allowed to return, so do not return int64. Refer to ValueError to return a value error just like built-in error function. If you want to emit multiple values, call the empty function, accept a filter for its argument, or call another built-in function, then use LoadInitModules of the module loader.

Example
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"math/big"
	"strconv"

	"github.com/itchyny/gojq"
)

func toFloat(x interface{}) (float64, bool) {
	switch x := x.(type) {
	case int:
		return float64(x), true
	case float64:
		return x, true
	case *big.Int:
		f, err := strconv.ParseFloat(x.String(), 64)
		return f, err == nil
	default:
		return 0.0, false
	}
}

func main() {
	query, err := gojq.Parse(".[] | f | f(3)")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(
		query,
		gojq.WithFunction("f", 0, 1, func(x interface{}, xs []interface{}) interface{} {
			if x, ok := toFloat(x); ok {
				if len(xs) == 1 {
					if y, ok := toFloat(xs[0]); ok {
						x *= y
					} else {
						return fmt.Errorf("f cannot be applied to: %v, %v", x, xs)
					}
				} else {
					x += 2
				}
				return x
			}
			return fmt.Errorf("f cannot be applied to: %v, %v", x, xs)
		}),
	)
	if err != nil {
		log.Fatalln(err)
	}
	input := []interface{}{0, 1, 2.5, json.Number("10000000000000000000000000000000000000000")}
	iter := code.Run(input)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

6
9
13.5
3e+40

func WithInputIter added in v0.10.0

func WithInputIter(inputIter Iter) CompilerOption

WithInputIter is a compiler option for input iterator used by input(s)/0. Note that input and inputs functions are not allowed by default. We have to distinguish the query input and the values for input(s) functions. For example, consider using inputs with --null-input. If you want to allow input(s) functions, create an Iter and use WithInputIter option.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse("reduce inputs as $x (0; . + $x)")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(
		query,
		gojq.WithInputIter(gojq.NewIter(1, 2, 3, 4, 5)),
	)
	if err != nil {
		log.Fatalln(err)
	}
	iter := code.Run(nil)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

15

func WithIterFunction added in v0.12.4

func WithIterFunction(name string, minarity, maxarity int,
	f func(interface{}, []interface{}) Iter) CompilerOption

WithIterFunction is a compiler option for adding a custom iterator function. This is like the WithFunction option, but you can add a function which returns an Iter to emit multiple values. You cannot define both iterator and non-iterator functions of the same name (with possibly different arities). See also NewIter, which can be used to convert values or an error to an Iter.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

// Implementation of range/2 using WithIterFunction option.
type rangeIter struct {
	value, max int
}

func (iter *rangeIter) Next() (interface{}, bool) {
	if iter.value >= iter.max {
		return nil, false
	}
	v := iter.value
	iter.value++
	return v, true
}

func main() {
	query, err := gojq.Parse("f(3; 7)")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(
		query,
		gojq.WithIterFunction("f", 2, 2, func(_ interface{}, xs []interface{}) gojq.Iter {
			if x, ok := xs[0].(int); ok {
				if y, ok := xs[1].(int); ok {
					return &rangeIter{x, y}
				}
			}
			return gojq.NewIter(fmt.Errorf("f cannot be applied to: %v", xs))
		}),
	)
	if err != nil {
		log.Fatalln(err)
	}
	iter := code.Run(nil)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

3
4
5
6

func WithModuleLoader added in v0.8.0

func WithModuleLoader(moduleLoader ModuleLoader) CompilerOption

WithModuleLoader is a compiler option for module loader. If you want to load modules from the filesystem, use NewModuleLoader.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

type moduleLoader struct{}

func (*moduleLoader) LoadModule(name string) (*gojq.Query, error) {
	switch name {
	case "module1":
		return gojq.Parse(`
			module { name: "module1", test: 42 };
			import "module2" as foo;
			def f: foo::f;
		`)
	case "module2":
		return gojq.Parse(`
			def f: .foo;
		`)
	}
	return nil, fmt.Errorf("module not found: %q", name)
}

func main() {
	query, err := gojq.Parse(`
		import "module1" as m;
		m::f
	`)
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(
		query,
		gojq.WithModuleLoader(&moduleLoader{}),
	)
	if err != nil {
		log.Fatalln(err)
	}
	input := map[string]interface{}{"foo": 42}
	iter := code.Run(input)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

42

func WithVariables added in v0.8.0

func WithVariables(variables []string) CompilerOption

WithVariables is a compiler option for variable names. The variables can be used in the query. You have to give the values to code.Run in the same order.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse("$x * 100 + $y, $z")
	if err != nil {
		log.Fatalln(err)
	}
	code, err := gojq.Compile(
		query,
		gojq.WithVariables([]string{
			"$x", "$y", "$z",
		}),
	)
	if err != nil {
		log.Fatalln(err)
	}
	iter := code.Run(nil, 12, 42, 128)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

1242
128

type ConstArray added in v0.8.0

type ConstArray struct {
	Elems []*ConstTerm
}

ConstArray ...

func (*ConstArray) String added in v0.8.0

func (e *ConstArray) String() string

type ConstObject added in v0.8.0

type ConstObject struct {
	KeyVals []*ConstObjectKeyVal
}

ConstObject ...

func (*ConstObject) String added in v0.8.0

func (e *ConstObject) String() string

func (*ConstObject) ToValue added in v0.10.0

func (e *ConstObject) ToValue() map[string]interface{}

ToValue converts the object to map[string]interface{}.

type ConstObjectKeyVal added in v0.8.0

type ConstObjectKeyVal struct {
	Key       string
	KeyString string
	Val       *ConstTerm
}

ConstObjectKeyVal ...

func (*ConstObjectKeyVal) String added in v0.8.0

func (e *ConstObjectKeyVal) String() string

type ConstTerm added in v0.8.0

type ConstTerm struct {
	Object *ConstObject
	Array  *ConstArray
	Number string
	Str    string
	Null   bool
	True   bool
	False  bool
}

ConstTerm ...

func (*ConstTerm) String added in v0.8.0

func (e *ConstTerm) String() string

type Foreach added in v0.3.0

type Foreach struct {
	Term    *Term
	Pattern *Pattern
	Start   *Query
	Update  *Query
	Extract *Query
}

Foreach ...

func (*Foreach) String added in v0.4.0

func (e *Foreach) String() string

type Func added in v0.1.0

type Func struct {
	Name string
	Args []*Query
}

Func ...

func (*Func) String added in v0.4.0

func (e *Func) String() string

type FuncDef added in v0.1.0

type FuncDef struct {
	Name string
	Args []string
	Body *Query
}

FuncDef ...

func (*FuncDef) Minify added in v0.10.2

func (e *FuncDef) Minify()

Minify ...

func (*FuncDef) String added in v0.4.0

func (e *FuncDef) String() string

type If added in v0.1.0

type If struct {
	Cond *Query
	Then *Query
	Elif []*IfElif
	Else *Query
}

If ...

func (*If) String added in v0.4.0

func (e *If) String() string

type IfElif added in v0.4.0

type IfElif struct {
	Cond *Query
	Then *Query
}

IfElif ...

func (*IfElif) String added in v0.4.0

func (e *IfElif) String() string

type Import added in v0.8.0

type Import struct {
	ImportPath  string
	ImportAlias string
	IncludePath string
	Meta        *ConstObject
}

Import ...

func (*Import) String added in v0.8.0

func (e *Import) String() string

type Index added in v0.2.0

type Index struct {
	Name    string
	Str     *String
	Start   *Query
	End     *Query
	IsSlice bool
}

Index ...

func (*Index) String added in v0.3.0

func (e *Index) String() string

type Iter added in v0.4.0

type Iter interface {
	Next() (interface{}, bool)
}

Iter is an interface for an iterator.

func NewIter added in v0.12.4

func NewIter(values ...interface{}) Iter

NewIter creates a new Iter from values.

type Label added in v0.3.0

type Label struct {
	Ident string
	Body  *Query
}

Label ...

func (*Label) String added in v0.4.0

func (e *Label) String() string

type ModuleLoader added in v0.8.0

type ModuleLoader interface{}

ModuleLoader is an interface for loading modules.

Implement following optional methods. Use NewModuleLoader to load local modules.

LoadModule(string) (*Query, error)
LoadModuleWithMeta(string, map[string]interface{}) (*Query, error)
LoadInitModules() ([]*Query, error)
LoadJSON(string) (interface{}, error)
LoadJSONWithMeta(string, map[string]interface{}) (interface{}, error)

func NewModuleLoader added in v0.10.4

func NewModuleLoader(paths []string) ModuleLoader

NewModuleLoader creates a new ModuleLoader reading local modules in the paths.

type Object

type Object struct {
	KeyVals []*ObjectKeyVal
}

Object ...

func (*Object) String added in v0.4.0

func (e *Object) String() string

type ObjectKeyVal added in v0.4.0

type ObjectKeyVal struct {
	Key           string
	KeyString     *String
	KeyQuery      *Query
	Val           *ObjectVal
	KeyOnly       string
	KeyOnlyString *String
}

ObjectKeyVal ...

func (*ObjectKeyVal) String added in v0.4.0

func (e *ObjectKeyVal) String() string

type ObjectVal added in v0.7.0

type ObjectVal struct {
	Queries []*Query
}

ObjectVal ...

func (*ObjectVal) String added in v0.7.0

func (e *ObjectVal) String() string

type Operator added in v0.1.0

type Operator int

Operator ...

const (
	OpPipe Operator = iota + 1
	OpComma
	OpAdd
	OpSub
	OpMul
	OpDiv
	OpMod
	OpEq
	OpNe
	OpGt
	OpLt
	OpGe
	OpLe
	OpAnd
	OpOr
	OpAlt
	OpAssign
	OpModify
	OpUpdateAdd
	OpUpdateSub
	OpUpdateMul
	OpUpdateDiv
	OpUpdateMod
	OpUpdateAlt
)

Operators ...

func (Operator) GoString added in v0.4.0

func (op Operator) GoString() (str string)

GoString implements GoStringer.

func (Operator) String added in v0.1.0

func (op Operator) String() string

String implements Stringer.

type Pattern added in v0.3.0

type Pattern struct {
	Name   string
	Array  []*Pattern
	Object []*PatternObject
}

Pattern ...

func (*Pattern) String added in v0.4.0

func (e *Pattern) String() string

type PatternObject added in v0.4.0

type PatternObject struct {
	Key       string
	KeyString *String
	KeyQuery  *Query
	Val       *Pattern
	KeyOnly   string
}

PatternObject ...

func (*PatternObject) String added in v0.4.0

func (e *PatternObject) String() string

type Query

type Query struct {
	Meta     *ConstObject
	Imports  []*Import
	FuncDefs []*FuncDef
	Term     *Term
	Left     *Query
	Op       Operator
	Right    *Query
	Func     string
}

Query represents the abstract syntax tree of a jq query.

func Parse added in v0.1.0

func Parse(src string) (*Query, error)

Parse parses a query.

func (*Query) Run added in v0.1.0

func (e *Query) Run(v interface{}) Iter

Run the query.

It is safe to call this method of a *Query in multiple goroutines.

Example
package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse(".foo | ..")
	if err != nil {
		log.Fatalln(err)
	}
	input := map[string]interface{}{"foo": []interface{}{1, 2, 3}}
	iter := query.Run(input)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}

}
Output:

[]interface {}{1, 2, 3}
1
2
3

func (*Query) RunWithContext added in v0.8.0

func (e *Query) RunWithContext(ctx context.Context, v interface{}) Iter

RunWithContext runs the query with context.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse("def f: f; f, f")
	if err != nil {
		log.Fatalln(err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()
	iter := query.RunWithContext(ctx, nil)
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			fmt.Println(err)
			continue
		}
		_ = v
	}

}
Output:

context deadline exceeded

func (*Query) String added in v0.4.0

func (e *Query) String() string

type Reduce added in v0.3.0

type Reduce struct {
	Term    *Term
	Pattern *Pattern
	Start   *Query
	Update  *Query
}

Reduce ...

func (*Reduce) String added in v0.4.0

func (e *Reduce) String() string

type String added in v0.11.0

type String struct {
	Str     string
	Queries []*Query
}

String ...

func (*String) String added in v0.11.0

func (e *String) String() string

type Suffix

type Suffix struct {
	Index    *Index
	Iter     bool
	Optional bool
	Bind     *Bind
}

Suffix ...

func (*Suffix) String added in v0.4.0

func (e *Suffix) String() string

type Term

type Term struct {
	Type       TermType
	Index      *Index
	Func       *Func
	Object     *Object
	Array      *Array
	Number     string
	Unary      *Unary
	Format     string
	Str        *String
	If         *If
	Try        *Try
	Reduce     *Reduce
	Foreach    *Foreach
	Label      *Label
	Break      string
	Query      *Query
	SuffixList []*Suffix
}

Term ...

func (*Term) String added in v0.1.0

func (e *Term) String() string

type TermType added in v0.11.0

type TermType int

TermType represents the type of Term.

const (
	TermTypeIdentity TermType = iota + 1
	TermTypeRecurse
	TermTypeNull
	TermTypeTrue
	TermTypeFalse
	TermTypeIndex
	TermTypeFunc
	TermTypeObject
	TermTypeArray
	TermTypeNumber
	TermTypeUnary
	TermTypeFormat
	TermTypeString
	TermTypeIf
	TermTypeTry
	TermTypeReduce
	TermTypeForeach
	TermTypeLabel
	TermTypeBreak
	TermTypeQuery
)

TermType list.

func (TermType) GoString added in v0.11.0

func (termType TermType) GoString() (str string)

GoString implements GoStringer.

type Try added in v0.2.0

type Try struct {
	Body  *Query
	Catch *Query
}

Try ...

func (*Try) String added in v0.4.0

func (e *Try) String() string

type Unary added in v0.4.0

type Unary struct {
	Op   Operator
	Term *Term
}

Unary ...

func (*Unary) String added in v0.4.0

func (e *Unary) String() string

type ValueError added in v0.12.2

type ValueError interface {
	error
	Value() interface{}
}

ValueError is an interface for errors with a value for internal function. Return an error implementing this interface when you want to catch error values (not error messages) by try-catch, just like built-in error function. Refer to WithFunction to add a custom internal function.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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