Select Git revision
expr_test.go
expr.go 1.48 KiB
package expr
import (
"regexp"
"strings"
"git.perx.ru/perxis/perxis-go/pkg/data"
compiler2 "github.com/antonmedv/expr/compiler"
"github.com/antonmedv/expr/parser"
"github.com/antonmedv/expr/vm"
"golang.org/x/net/context"
)
var (
additionalFunctions = []string{"contains", "startsWith", "endsWith", "and", "or", "in", "not"}
isExpression = regexp.MustCompile(`[()}{<>=|&%*+\-\/\]\[\\]`).MatchString
)
const EnvContextKey = "$context"
func Eval(ctx context.Context, input string, env map[string]interface{}) (interface{}, error) {
tree, err := parser.Parse(input)
if err != nil {
return nil, err
}
e := GetEnv(ctx)
if e == nil {
e = make(map[string]interface{})
}
for k, v := range env {
e[k] = v
}
e[EnvContextKey] = ctx
cfg := GetDefaultConfig(e)
env, _ = cfg.Env.(map[string]interface{})
program, err := compiler2.Compile(tree, nil)
if err != nil {
return nil, err
}
output, err := vm.Run(program, env)
if err != nil {
return nil, err
}
return output, nil
}
func EvalKV(ctx context.Context, input string, kv ...interface{}) (interface{}, error) {
m := make(map[string]interface{})
for i := 0; i < len(kv)/2; i++ {
key, ok := kv[i].(string)
if !ok {
panic("key should be string")
}
m[key] = kv[i+1]
}
return Eval(ctx, input, m)
}
func IsExpression(input string) bool {
if isExpression(input) {
return true
}
for _, s := range strings.Fields(input) {
if data.Contains(s, additionalFunctions) {
return true
}
}
return false
}