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 }