Skip to content

Commit a107074

Browse files
authored
feat: decouple function caller from interpreter (#84)
Signed-off-by: Charles-Edouard Brétéché <[email protected]>
1 parent aa8d53e commit a107074

File tree

7 files changed

+109
-76
lines changed

7 files changed

+109
-76
lines changed

jp.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package jmespath
33
import (
44
"github.com/jmespath-community/go-jmespath/pkg/api"
55
"github.com/jmespath-community/go-jmespath/pkg/functions"
6+
"github.com/jmespath-community/go-jmespath/pkg/interpreter"
67
"github.com/jmespath-community/go-jmespath/pkg/parsing"
78
)
89

@@ -16,6 +17,12 @@ var (
1617
Search = api.Search
1718
)
1819

20+
// interpreter types
21+
22+
type Option = interpreter.Option
23+
24+
var WithFunctionCaller = interpreter.WithFunctionCaller
25+
1926
// parsing types
2027

2128
type SyntaxError = parsing.SyntaxError

pkg/api/api.go

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,59 @@ package api
33
import (
44
"strconv"
55

6-
"github.com/jmespath-community/go-jmespath/pkg/functions"
76
"github.com/jmespath-community/go-jmespath/pkg/interpreter"
87
"github.com/jmespath-community/go-jmespath/pkg/parsing"
98
)
109

1110
// JMESPath is the representation of a compiled JMES path query. A JMESPath is
1211
// safe for concurrent use by multiple goroutines.
1312
type JMESPath interface {
14-
Search(interface{}) (interface{}, error)
13+
Search(interface{}, ...interpreter.Option) (interface{}, error)
1514
}
1615

1716
type jmesPath struct {
18-
node parsing.ASTNode
19-
caller interpreter.FunctionCaller
17+
node parsing.ASTNode
2018
}
2119

22-
func newJMESPath(node parsing.ASTNode, funcs ...functions.FunctionEntry) JMESPath {
20+
func newJMESPath(node parsing.ASTNode) JMESPath {
2321
return jmesPath{
24-
node: node,
25-
caller: interpreter.NewFunctionCaller(funcs...),
22+
node: node,
2623
}
2724
}
2825

2926
// Compile parses a JMESPath expression and returns, if successful, a JMESPath
3027
// object that can be used to match against data.
31-
func Compile(expression string, funcs ...functions.FunctionEntry) (JMESPath, error) {
28+
func Compile(expression string) (JMESPath, error) {
3229
parser := parsing.NewParser()
3330
ast, err := parser.Parse(expression)
3431
if err != nil {
3532
return nil, err
3633
}
37-
var f []functions.FunctionEntry
38-
f = append(f, functions.GetDefaultFunctions()...)
39-
f = append(f, funcs...)
40-
return newJMESPath(ast, f...), nil
34+
return newJMESPath(ast), nil
4135
}
4236

4337
// MustCompile is like Compile but panics if the expression cannot be parsed.
4438
// It simplifies safe initialization of global variables holding compiled
4539
// JMESPaths.
46-
func MustCompile(expression string, funcs ...functions.FunctionEntry) JMESPath {
47-
jmespath, err := Compile(expression, funcs...)
40+
func MustCompile(expression string) JMESPath {
41+
jmespath, err := Compile(expression)
4842
if err != nil {
4943
panic(`jmespath: Compile(` + strconv.Quote(expression) + `): ` + err.Error())
5044
}
5145
return jmespath
5246
}
5347

5448
// Search evaluates a JMESPath expression against input data and returns the result.
55-
func (jp jmesPath) Search(data interface{}) (interface{}, error) {
56-
intr := interpreter.NewInterpreter(data, jp.caller, nil)
57-
return intr.Execute(jp.node, data)
49+
func (jp jmesPath) Search(data interface{}, opts ...interpreter.Option) (interface{}, error) {
50+
intr := interpreter.NewInterpreter(data, nil)
51+
return intr.Execute(jp.node, data, opts...)
5852
}
5953

6054
// Search evaluates a JMESPath expression against input data and returns the result.
61-
func Search(expression string, data interface{}, funcs ...functions.FunctionEntry) (interface{}, error) {
62-
compiled, err := Compile(expression, funcs...)
55+
func Search(expression string, data interface{}, opts ...interpreter.Option) (interface{}, error) {
56+
compiled, err := Compile(expression)
6357
if err != nil {
6458
return nil, err
6559
}
66-
return compiled.Search(data)
60+
return compiled.Search(data, opts...)
6761
}

pkg/api/api_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/jmespath-community/go-jmespath/pkg/functions"
8+
"github.com/jmespath-community/go-jmespath/pkg/interpreter"
89
"github.com/stretchr/testify/assert"
910
)
1011

@@ -142,7 +143,15 @@ func TestSearch(t *testing.T) {
142143
for _, tt := range tests {
143144
t.Run(tt.name, func(t *testing.T) {
144145
assert := assert.New(t)
145-
got, err := Search(tt.args.expression, tt.args.data, tt.args.funcs...)
146+
var opts []interpreter.Option
147+
if len(tt.args.funcs) != 0 {
148+
var f []functions.FunctionEntry
149+
f = append(f, functions.GetDefaultFunctions()...)
150+
f = append(f, tt.args.funcs...)
151+
caller := interpreter.NewFunctionCaller(f...)
152+
opts = append(opts, interpreter.WithFunctionCaller(caller))
153+
}
154+
got, err := Search(tt.args.expression, tt.args.data, opts...)
146155
assert.Equal(tt.wantErr, err != nil)
147156
assert.Equal(tt.want, got)
148157
})

0 commit comments

Comments
 (0)