Documentation ¶
Index ¶
- func AsBool() conf.Option
- func AsFloat64() conf.Option
- func AsInt64() conf.Option
- func Compile(input string, ops ...conf.Option) (*vm.Program, error)
- func Env(i interface{}) conf.Option
- func Eval(input string, env interface{}) (interface{}, error)
- func Operator(operator string, fn ...string) conf.Option
- func Optimize(b bool) conf.Option
- func Parse(input string, ops ...conf.Option) (*vm.Program, error)deprecated
- func Run(program *vm.Program, env interface{}) (interface{}, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AsBool ¶ added in v1.2.0
AsBool tells the compiler to expect boolean result.
Example ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { env := map[string]int{ "foo": 0, } program, err := expr.Compile("foo >= 0", expr.Env(env), expr.AsBool()) if err != nil { fmt.Printf("%v", err) return } output, err := expr.Run(program, env) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output.(bool)) }
Output: true
func AsFloat64 ¶ added in v1.2.0
AsFloat64 tells the compiler to expect float64 result.
Example ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { program, err := expr.Compile("42", expr.AsFloat64()) if err != nil { fmt.Printf("%v", err) return } output, err := expr.Run(program, nil) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output.(float64)) }
Output: 42
func AsInt64 ¶ added in v1.2.0
AsInt64 tells the compiler to expect int64 result.
Example ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { env := map[string]float64{ "foo": 3, } program, err := expr.Compile("foo + 2", expr.Env(env), expr.AsInt64()) if err != nil { fmt.Printf("%v", err) return } output, err := expr.Run(program, env) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output.(int64)) }
Output: 5
func Compile ¶ added in v1.2.0
Compile parses and compiles given input expression to bytecode program.
Example ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { env := map[string]interface{}{ "foo": 1, "bar": 99, } program, err := expr.Compile("foo in 1..99 and bar in 1..99", expr.Env(env)) if err != nil { fmt.Printf("%v", err) return } output, err := expr.Run(program, env) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: true
func Env ¶ added in v1.0.7
Env specifies expected input of env for type checks. If struct is passed, all fields will be treated as variables, as well as all fields of embedded structs and struct itself. If map is passed, all items will be treated as variables. Methods defined on this type will be available as functions.
Example ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { type Segment struct { Origin string } type Passengers struct { Adults int } type Request struct { Segments []*Segment Passengers *Passengers Marker string Meta map[string]interface{} } code := `Segments[0].Origin == "MOW" && Passengers.Adults == 2 && Marker == "test" && Meta["accept"]` program, err := expr.Compile(code, expr.Env(&Request{})) if err != nil { fmt.Printf("%v", err) return } request := &Request{ Segments: []*Segment{ {Origin: "MOW"}, }, Passengers: &Passengers{ Adults: 2, }, Marker: "test", Meta: map[string]interface{}{"accept": true}, } output, err := expr.Run(program, request) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: true
Example (With_undefined_variables) ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { env := map[string]interface{}{ "foo": 0, "bar": 0, } program, err := expr.Compile(`foo + (bar != nil ? bar : 2)`, expr.Env(env)) if err != nil { fmt.Printf("%v", err) return } request := map[string]interface{}{ "foo": 3, } output, err := expr.Run(program, request) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: 5
func Eval ¶
Eval parses, compiles and runs given input.
Example ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { output, err := expr.Eval("'hello world'", nil) if err != nil { fmt.Printf("err: %v", err) return } fmt.Printf("%v", output) }
Output: hello world
Example (Error) ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { output, err := expr.Eval("(boo + bar]", nil) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: syntax error: mismatched input ']' expecting ')' (1:11) | (boo + bar] | ..........^
Example (Map) ¶
package main import ( "fmt" "strings" "github.com/antonmedv/expr" ) func main() { env := map[string]interface{}{ "foo": 1, "bar": []string{"zero", "hello world"}, "swipe": func(in string) string { return strings.Replace(in, "world", "user", 1) }, } output, err := expr.Eval("swipe(bar[foo])", env) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: hello user
Example (Map_method) ¶
package main import ( "fmt" "strings" "github.com/antonmedv/expr" ) type mockMapEnv map[string]interface{} func (mockMapEnv) Swipe(in string) string { return strings.Replace(in, "world", "user", 1) } func main() { env := mockMapEnv{ "foo": 1, "bar": []string{"zero", "hello world"}, } program, err := expr.Compile("Swipe(bar[foo])", expr.Env(env)) if err != nil { fmt.Printf("%v", err) return } output, err := expr.Run(program, env) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: hello user
Example (Marshal) ¶
package main import ( "encoding/json" "fmt" "github.com/antonmedv/expr" "github.com/antonmedv/expr/vm" ) func main() { env := map[string]int{ "foo": 1, "bar": 2, } program, err := expr.Compile("(foo + bar) in [1, 2, 3]", expr.Env(env)) if err != nil { fmt.Printf("%v", err) return } b, err := json.Marshal(program) if err != nil { fmt.Printf("%v", err) return } unmarshaledProgram := &vm.Program{} err = json.Unmarshal(b, unmarshaledProgram) if err != nil { fmt.Printf("%v", err) return } output, err := expr.Run(unmarshaledProgram, env) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: true
Example (Matches) ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { output, err := expr.Eval(`"a" matches "a("`, nil) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: error parsing regexp: missing closing ): `a(` (1:13) | "a" matches "a(" | ............^
Example (Struct) ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { type C struct{ C int } type B struct{ B *C } type A struct{ A B } env := A{B{&C{42}}} output, err := expr.Eval("A.B.C", env) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: 42
func Operator ¶ added in v1.2.0
Operator allows to override binary operator with function.
Example ¶
package main import ( "fmt" "github.com/antonmedv/expr" ) func main() { type Place struct { Code string } type Segment struct { Origin Place } type Helpers struct { PlaceEq func(p Place, s string) bool } type Request struct { Segments []*Segment Helpers } code := `Segments[0].Origin == "MOW" && PlaceEq(Segments[0].Origin, "MOW")` program, err := expr.Compile(code, expr.Env(&Request{}), expr.Operator("==", "PlaceEq")) if err != nil { fmt.Printf("%v", err) return } request := &Request{ Segments: []*Segment{ {Origin: Place{Code: "MOW"}}, }, Helpers: Helpers{PlaceEq: func(p Place, s string) bool { return p.Code == s }}, } output, err := expr.Run(program, request) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: true
Example (Time) ¶
package main import ( "fmt" "time" "github.com/antonmedv/expr" ) func main() { type Segment struct { Date time.Time } type Request struct { Segments []Segment Before func(a, b time.Time) bool Date func(s string) time.Time } code := `Date("2001-01-01") < Segments[0].Date` program, err := expr.Compile(code, expr.Env(&Request{}), expr.Operator("<", "Before")) if err != nil { fmt.Printf("%v", err) return } request := &Request{ Segments: []Segment{ {Date: time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC)}, }, Before: func(a, b time.Time) bool { return a.Before(b) }, Date: func(s string) time.Time { date, err := time.Parse("2006-01-02", s) if err != nil { panic(err) } return date }, } output, err := expr.Run(program, request) if err != nil { fmt.Printf("%v", err) return } fmt.Printf("%v", output) }
Output: true
Types ¶
This section is empty.