Documentation ¶
Overview ¶
Package gojq provides the parser and the interpreter of gojq. Please refer to Usage as a library for introduction.
Index ¶
- Constants
- func BinopTypeSwitch(l, r any, callbackInts func(_, _ int) any, ...) any
- func Compare(l, r any) int
- func Marshal(v any) ([]byte, error)
- func NormalizeNumber(v json.Number) any
- func NormalizeNumbers(v any) any
- func Preview(v any) string
- func TypeOf(v any) string
- func ValidNumber(s string) bool
- type Array
- type Bind
- type Code
- type CompilerOption
- func WithEnvironLoader(environLoader func() []string) CompilerOption
- func WithFunction(name string, minarity, maxarity int, f func(any, []any) any) CompilerOption
- func WithInputIter(inputIter Iter) CompilerOption
- func WithIterFunction(name string, minarity, maxarity int, f func(any, []any) Iter) CompilerOption
- func WithModuleLoader(moduleLoader ModuleLoader) CompilerOption
- func WithVariables(variables []string) CompilerOption
- type ConstArray
- type ConstObject
- type ConstObjectKeyVal
- type ConstTerm
- type Foreach
- type Func
- type FuncDef
- type HaltError
- type If
- type IfElif
- type Import
- type Index
- type Iter
- type JQValue
- type Label
- type ModuleLoader
- type Object
- type ObjectKeyVal
- type Operator
- type ParseError
- type PathValue
- type Pattern
- type PatternObject
- type Query
- type Reduce
- type String
- type Suffix
- type Term
- type TermType
- type Try
- type Unary
- type ValueError
Examples ¶
Constants ¶
const ( JQTypeArray = "array" JQTypeBoolean = "boolean" JQTypeNull = "null" JQTypeNumber = "number" JQTypeObject = "object" JQTypeString = "string" )
TODO: use in TypeOf?
Variables ¶
This section is empty.
Functions ¶
func BinopTypeSwitch ¶
func BinopTypeSwitch( l, r any, callbackInts func(_, _ int) any, callbackFloats func(_, _ float64) any, callbackBigInts func(_, _ *big.Int) any, callbackStrings func(_, _ string) any, callbackArrays func(_, _ []any) any, callbackMaps func(_, _ map[string]any) any, fallback func(_, _ any) any) any
BinopTypeSwitch helper for external binops re-exported instead of renamed to make it easier to follow upstream
func Compare ¶
Compare l and r, and returns jq-flavored comparison value. The result will be 0 if l == r, -1 if l < r, and +1 if l > r. This comparison is used by built-in operators and functions.
func Marshal ¶
Marshal returns the jq-flavored JSON encoding of v.
This method accepts only limited types (nil, bool, int, float64, *big.Int, string, []any, and map[string]any) 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 '<', '>', '&', '\u2028', and '\u2029'. These behaviors are based on the marshaler of jq command, and different from json.Marshal in the Go standard library. Note that the result is not safe to embed in HTML.
func NormalizeNumber ¶
func NormalizeNumbers ¶
func Preview ¶
Preview returns the preview string of v. The preview string is basically the same as the jq-flavored JSON encoding returned by Marshal, but is truncated by 30 bytes, and more efficient than truncating the result of Marshal.
This method is used by error messages of built-in operators and functions, and accepts only limited types (nil, bool, int, float64, *big.Int, string, []any, and map[string]any). Note that the maximum width and trailing strings on truncation may be changed in the future.
func TypeOf ¶
TypeOf returns the jq-flavored type name of v.
This method is used by built-in type/0 function, and accepts only limited types (nil, bool, int, float64, *big.Int, string, []any, and map[string]any).
func ValidNumber ¶
Types ¶
type Bind ¶
type Bind struct { Patterns []*Pattern `json:"patterns,omitempty"` Body *Query `json:"body,omitempty"` }
Bind ...
type Code ¶
type Code struct {
// contains filtered or unexported fields
}
Code is a compiled jq query.
func Compile ¶
func Compile(q *Query, options ...CompilerOption) (*Code, error)
Compile compiles a query.
Example ¶
package main import ( "fmt" "log" "github.com/wader/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([]any{ nil, "string", 42, []any{"foo"}, map[string]any{"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 ¶
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 in goroutines, to reuse a compiled *Code. But for arguments, do not give values sharing same data between goroutines.
Example ¶
package main import ( "fmt" "log" "github.com/wader/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]any{"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 ¶
RunWithContext runs the code with context.
Example ¶
package main import ( "context" "fmt" "log" "time" "github.com/wader/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 ¶
type CompilerOption func(*compiler)
CompilerOption is a compiler option.
func WithEnvironLoader ¶
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 reasons. You can specify os.Environ as argument if you allow to access.
Example ¶
package main import ( "fmt" "log" "github.com/wader/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 ¶
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/wader/gojq" ) func toFloat(x any) (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 any, xs []any) any { 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 := []any{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 ¶
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/wader/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 ¶
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/wader/gojq" ) // Implementation of range/2 using WithIterFunction option. type rangeIter struct { value, max int } func (iter *rangeIter) Next() (any, 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(_ any, xs []any) 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 ¶
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/wader/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 g: foo::f; `) case "module2": return gojq.Parse(` def f: .foo; `) case "module3": return gojq.Parse("") } return nil, fmt.Errorf("module not found: %q", name) } func main() { query, err := gojq.Parse(` import "module1" as m; m::g `) if err != nil { log.Fatalln(err) } code, err := gojq.Compile( query, gojq.WithModuleLoader(&moduleLoader{}), ) if err != nil { log.Fatalln(err) } input := map[string]any{"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 ¶
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/wader/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 ¶
type ConstArray struct {
Elems []*ConstTerm `json:"elems,omitempty"`
}
ConstArray ...
func (*ConstArray) String ¶
func (e *ConstArray) String() string
type ConstObject ¶
type ConstObject struct {
KeyVals []*ConstObjectKeyVal `json:"keyvals,omitempty"`
}
ConstObject ...
func (*ConstObject) String ¶
func (e *ConstObject) String() string
func (*ConstObject) ToValue ¶
func (e *ConstObject) ToValue() map[string]any
ToValue converts the object to map[string]any.
type ConstObjectKeyVal ¶
type ConstObjectKeyVal struct { Key string `json:"key,omitempty"` KeyString string `json:"key_string,omitempty"` Val *ConstTerm `json:"val,omitempty"` }
ConstObjectKeyVal ...
func (*ConstObjectKeyVal) String ¶
func (e *ConstObjectKeyVal) String() string
type ConstTerm ¶
type ConstTerm struct { Object *ConstObject `json:"object,omitempty"` Array *ConstArray `json:"array,omitempty"` Number string `json:"number,omitempty"` Str string `json:"str,omitempty"` Null bool `json:"null,omitempty"` True bool `json:"true,omitempty"` False bool `json:"false,omitempty"` }
ConstTerm ...
type Foreach ¶
type Foreach struct { Query *Query `json:"query,omitempty"` Pattern *Pattern `json:"pattern,omitempty"` Start *Query `json:"start,omitempty"` Update *Query `json:"update,omitempty"` Extract *Query `json:"extract,omitempty"` }
Foreach ...
type FuncDef ¶
type FuncDef struct { Name string `json:"name,omitempty"` Args []string `json:"args,omitempty"` Body *Query `json:"body,omitempty"` }
FuncDef ...
type HaltError ¶
type HaltError exitCodeError
HaltError is an error emitted by halt and halt_error functions. It implements ValueError, and if the value is nil, discard the error and stop the iteration. Consider a query like "1, halt, 2"; the first value is 1, and the second value is a HaltError with nil value. You might think the iterator should not emit an error this case, but it should so that we can recognize the halt error to stop the outer loop of iterating input values; echo 1 2 3 | gojq "., halt".
func (*HaltError) Value ¶
Value returns the value of the error. This implements ValueError, but halt error is not catchable by try-catch.
type If ¶
type If struct { Cond *Query `json:"cond,omitempty"` Then *Query `json:"then,omitempty"` Elif []*IfElif `json:"elif,omitempty"` Else *Query `json:"else,omitempty"` }
If ...
type Import ¶
type Import struct { ImportPath string `json:"import_path,omitempty"` ImportAlias string `json:"import_alias,omitempty"` IncludePath string `json:"include_path,omitempty"` Meta *ConstObject `json:"meta,omitempty"` }
Import ...
type Index ¶
type Index struct { Name string `json:"name,omitempty"` Str *String `json:"str,omitempty"` Start *Query `json:"start,omitempty"` End *Query `json:"end,omitempty"` IsSlice bool `json:"is_slice,omitempty"` }
Index ...
type JQValue ¶
type JQValue interface { // JQValueLength is length of value, ex: value | length JQValueLength() any // int // JQValueSliceLen slice length JQValueSliceLen() any // int // JQValueIndex look up index for value, ex: value[index] // index -1 outside after slice, -2 outside before slice JQValueIndex(index int) any // value // JQValueSlice slices value, ex: value[start:end] // start and end indexes are translated and clamped using JQValueSliceLen JQValueSlice(start int, end int) any // []any // JQValueKey look up key value of value: ex: value[name] JQValueKey(name string) any // value // JQValueEach each of value, ex: value[] JQValueEach() any // []PathValue // JQValueKeys keys for value, ex: value | keys JQValueKeys() any // []string // JQValueHas check if value has key, ex: value | has(key) JQValueHas(key any) any // bool // JQValueType type of value, ex: value | type JQValueType() string // a JQType* constant // JQValueToNumber is value represented as a number, ex: value | tonumber JQValueToNumber() any // number // JQValueToString is value represented as a string, ex: value | tostring JQValueToString() any // string // JQValue value represented as a gojq compatible value JQValueToGoJQ() any // value }
JQValue represents something that can be a jq value All functions with return type any can return error on error array = []any boolean = bool null = nil number = int | float64 | *big.Int object = map[string]any string = string value = number | boolean | string | array | object | null
type ModuleLoader ¶
type ModuleLoader any
ModuleLoader is the interface for loading modules.
Implement following optional methods. Use NewModuleLoader to load local modules.
LoadInitModules() ([]*Query, error) LoadModule(string) (*Query, error) LoadModuleWithMeta(string, map[string]any) (*Query, error) LoadJSON(string) (any, error) LoadJSONWithMeta(string, map[string]any) (any, error)
func NewModuleLoader ¶
func NewModuleLoader(paths []string) ModuleLoader
NewModuleLoader creates a new ModuleLoader loading local modules in the paths. Note that user can load modules outside the paths using "search" path of metadata. Empty paths are ignored, so specify "." for the current working directory.
type ObjectKeyVal ¶
type ObjectKeyVal struct { Key string `json:"key,omitempty"` KeyString *String `json:"key_string,omitempty"` KeyQuery *Query `json:"key_query,omitempty"` Val *Query `json:"val,omitempty"` }
ObjectKeyVal ...
func (*ObjectKeyVal) String ¶
func (e *ObjectKeyVal) String() string
type Operator ¶
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 OperatorFromString ¶
String implements fmt.Stringer.
func (Operator) GoString ¶
GoString implements fmt.GoStringer.
func (Operator) MarshalJSON ¶
func (*Operator) UnmarshalJSON ¶
type ParseError ¶
type ParseError struct { Offset int // the error occurred after reading Offset bytes Token string // the Token that caused the error (may be empty) // contains filtered or unexported fields }
ParseError represents a description of a query parsing error.
func (*ParseError) Error ¶
func (err *ParseError) Error() string
type PathValue ¶
type PathValue struct {
Path, Value any
}
PathValue is a part of a jq path expression
type Pattern ¶
type Pattern struct { Name string `json:"name,omitempty"` Array []*Pattern `json:"array,omitempty"` Object []*PatternObject `json:"object,omitempty"` }
Pattern ...
type PatternObject ¶
type PatternObject struct { Key string `json:"key,omitempty"` KeyString *String `json:"key_string,omitempty"` KeyQuery *Query `json:"key_query,omitempty"` Val *Pattern `json:"val,omitempty"` }
PatternObject ...
func (*PatternObject) String ¶
func (e *PatternObject) String() string
type Query ¶
type Query struct { Meta *ConstObject `json:"meta,omitempty"` Imports []*Import `json:"imports,omitempty"` FuncDefs []*FuncDef `json:"func_defs,omitempty"` Term *Term `json:"term,omitempty"` Left *Query `json:"left,omitempty"` Op Operator `json:"op,omitempty"` Right *Query `json:"right,omitempty"` Func string `json:"func,omitempty"` }
Query represents the abstract syntax tree of a jq query.
func Parse ¶
Parse a query string, and returns the query struct.
If parsing failed, it returns an error of type *ParseError, which has the byte offset and the invalid token. The byte offset is the scanned bytes when the error occurred. The token is empty if the error occurred after scanning the entire query string.
func (*Query) Run ¶
Run the query.
It is safe to call this method in goroutines, to reuse a parsed *Query. But for arguments, do not give values sharing same data between goroutines.
Example ¶
package main import ( "fmt" "log" "github.com/wader/gojq" ) func main() { query, err := gojq.Parse(".foo | ..") if err != nil { log.Fatalln(err) } input := map[string]any{"foo": []any{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 ¶
RunWithContext runs the query with context.
Example ¶
package main import ( "context" "fmt" "log" "time" "github.com/wader/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
type Reduce ¶
type Reduce struct { Query *Query `json:"query,omitempty"` Pattern *Pattern `json:"pattern,omitempty"` Start *Query `json:"start,omitempty"` Update *Query `json:"update,omitempty"` }
Reduce ...
type String ¶
type String struct { Str string `json:"str,omitempty"` Queries []*Query `json:"queries,omitempty"` }
String ...
type Suffix ¶
type Suffix struct { Index *Index `json:"index,omitempty"` Iter bool `json:"iter,omitempty"` Optional bool `json:"optional,omitempty"` Bind *Bind `json:"bind,omitempty"` }
Suffix ...
type Term ¶
type Term struct { Type TermType `json:"type,omitempty"` Index *Index `json:"index,omitempty"` Func *Func `json:"func,omitempty"` Object *Object `json:"object,omitempty"` Array *Array `json:"array,omitempty"` Number string `json:"number,omitempty"` Unary *Unary `json:"unary,omitempty"` Format string `json:"format,omitempty"` Str *String `json:"str,omitempty"` If *If `json:"if,omitempty"` Try *Try `json:"try,omitempty"` Reduce *Reduce `json:"reduce,omitempty"` Foreach *Foreach `json:"foreach,omitempty"` Label *Label `json:"label,omitempty"` Break string `json:"break,omitempty"` Query *Query `json:"query,omitempty"` SuffixList []*Suffix `json:"suffix_list,omitempty"` }
Term ...
type TermType ¶
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 TermTypeFromString ¶
GoString implements fmt.GoStringer.
func (TermType) GoString ¶
GoString implements fmt.GoStringer.
func (TermType) MarshalJSON ¶
func (*TermType) UnmarshalJSON ¶
type ValueError ¶
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.