118 lines
2.0 KiB
Go
118 lines
2.0 KiB
Go
package expr
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/PaesslerAG/gval"
|
|
)
|
|
|
|
type (
|
|
Parsable interface {
|
|
Parse(string) (Evaluable, error)
|
|
ParseEvaluators(ee ...Evaluator) error
|
|
}
|
|
|
|
Evaluable interface {
|
|
Eval(context.Context, *Vars) (interface{}, error)
|
|
Test(context.Context, *Vars) (bool, error)
|
|
}
|
|
|
|
Evaluator interface {
|
|
GetExpr() string
|
|
SetEval(eval Evaluable)
|
|
}
|
|
|
|
gvalParser struct {
|
|
lang gval.Language
|
|
}
|
|
|
|
gvalEval struct {
|
|
evaluable gval.Evaluable
|
|
}
|
|
)
|
|
|
|
var (
|
|
parser gval.Language
|
|
)
|
|
|
|
func init() {
|
|
parser = gval.Full(AllFunctions()...)
|
|
}
|
|
|
|
// Parser returns global parser instance
|
|
func Parser() gval.Language {
|
|
return parser
|
|
}
|
|
|
|
func NewParser() Parsable {
|
|
return NewGvalParser()
|
|
}
|
|
|
|
func NewGvalParser() *gvalParser {
|
|
return &gvalParser{lang: Parser()}
|
|
}
|
|
|
|
func (p *gvalParser) Parse(expr string) (Evaluable, error) {
|
|
var (
|
|
ge = &gvalEval{}
|
|
err error
|
|
)
|
|
|
|
if ge.evaluable, err = p.lang.NewEvaluable(expr); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ge, err
|
|
}
|
|
|
|
func (p *gvalParser) ParseEvaluators(ee ...Evaluator) error {
|
|
for _, e := range ee {
|
|
evaluable, err := p.Parse(e.GetExpr())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
e.SetEval(evaluable)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (e *gvalEval) Eval(ctx context.Context, scope *Vars) (interface{}, error) {
|
|
return e.evaluable(ctx, scope)
|
|
}
|
|
|
|
func (e *gvalEval) Test(ctx context.Context, scope *Vars) (bool, error) {
|
|
r, err := e.evaluable(ctx, scope)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return !isEmpty(r), nil
|
|
}
|
|
|
|
func AllFunctions() []gval.Language {
|
|
ff := make([]gval.Language, 0, 100)
|
|
|
|
ff = append(ff, GenericFunctions()...)
|
|
ff = append(ff, StringFunctions()...)
|
|
ff = append(ff, JsonFunctions()...)
|
|
ff = append(ff, NumericFunctions()...)
|
|
ff = append(ff, TimeFunctions()...)
|
|
ff = append(ff, ArrayFunctions()...)
|
|
ff = append(ff, KvFunctions()...)
|
|
|
|
return ff
|
|
}
|
|
|
|
// utility function for examples
|
|
func eval(e string, p interface{}) {
|
|
result, err := Parser().Evaluate(e, p)
|
|
if err != nil {
|
|
fmt.Printf("error: %v", err)
|
|
} else {
|
|
fmt.Printf("%+v", UntypedValue(result))
|
|
}
|
|
}
|