Documentation
¶
Overview ¶
Package anyexpr is a generic expression compilation and evaluation library.
It wraps expr-lang with a typed compiler, a library of built-in string and pattern matching functions, and a compile-once-run-many execution model.
The typical workflow is:
- Create a Compiler parameterised on your environment struct.
- Compile expression strings into Program values using Compiler.Compile.
- Evaluate programs against environment values using Program.Match or Program.Eval.
Expressions are validated at compile time against the fields and methods of the environment type, catching typos and type errors before evaluation.
Example ¶
package main
import (
"fmt"
"log"
"github.com/rhyselsmore/anyexpr"
)
func main() {
type Email struct {
From string
Subject string
Body string
}
compiler, err := anyexpr.NewCompiler[Email]()
if err != nil {
log.Fatal(err)
}
src := anyexpr.NewSource("invoice-filter",
`has(Subject, "invoice") && ends(From, "stripe.com")`)
prog, err := compiler.Compile(src)
if err != nil {
log.Fatal(err)
}
msg := Email{
From: "billing@stripe.com",
Subject: "Your January Invoice",
Body: "...",
}
matched, err := prog.Match(msg)
if err != nil {
log.Fatal(err)
}
fmt.Println(matched)
}
Output: true
Example (Check) ¶
package main
import (
"fmt"
"log"
"github.com/rhyselsmore/anyexpr"
)
func main() {
type Env struct {
Name string
}
compiler, err := anyexpr.NewCompiler[Env]()
if err != nil {
log.Fatal(err)
}
sources := []*anyexpr.Source{
anyexpr.NewSource("rule-1", `has(Name, "alice")`),
anyexpr.NewSource("rule-2", `starts(Name, "b")`),
}
if err := compiler.Check(sources); err != nil {
log.Fatal(err)
}
fmt.Println("all valid")
}
Output: all valid
Example (CustomFunction) ¶
package main
import (
"fmt"
"log"
"github.com/rhyselsmore/anyexpr"
)
func main() {
type Env struct {
Value string
}
compiler, err := anyexpr.NewCompiler[Env](
anyexpr.WithFunction("reverse", func(params ...any) (any, error) {
s := params[0].(string)
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes), nil
}),
)
if err != nil {
log.Fatal(err)
}
prog, err := compiler.Compile(
anyexpr.NewSource("palindrome", `eq(Value, reverse(Value))`))
if err != nil {
log.Fatal(err)
}
matched, _ := prog.Match(Env{Value: "racecar"})
fmt.Println(matched)
}
Output: true
Example (Eval) ¶
package main
import (
"fmt"
"log"
"github.com/rhyselsmore/anyexpr"
)
func main() {
type Email struct {
From string
Email string
}
compiler, err := anyexpr.NewCompiler[Email]()
if err != nil {
log.Fatal(err)
}
prog, err := compiler.Compile(
anyexpr.NewSource("extract-domain", `email_domain(Email)`))
if err != nil {
log.Fatal(err)
}
result, err := prog.Eval(Email{
From: "Alice",
Email: "alice@example.com",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result)
}
Output: example.com
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrDuplicateFunction is returned when a function name is registered // more than once on the same compiler. ErrDuplicateFunction = errors.New("anyexpr: duplicate function registration") // ErrBuiltinConflict is returned when WithFunction is called with a // name that matches a built-in function. Use ReplaceFunction instead. ErrBuiltinConflict = errors.New("anyexpr: function name conflicts with built-in") // ErrNotBuiltin is returned when ReplaceFunction is called with a // name that is not a known built-in. ErrNotBuiltin = errors.New("anyexpr: name is not a built-in function") // ErrCompile is returned when an expression fails to parse or type-check. ErrCompile = errors.New("anyexpr: compilation failed") // ErrTypeMismatch is returned when Match is called on an expression // that does not return bool. ErrTypeMismatch = errors.New("anyexpr: expression return type mismatch") )
Functions ¶
This section is empty.
Types ¶
type Compiler ¶
type Compiler[T any] struct { // contains filtered or unexported fields }
Compiler compiles expression sources into programs. It is parameterised on T, the type of the environment passed to expressions at evaluation time. A Compiler is immutable after construction and safe for concurrent use.
func NewCompiler ¶
func NewCompiler[T any](opts ...CompilerOpt) (*Compiler[T], error)
NewCompiler creates a new Compiler. Options configure custom functions and built-in overrides. Returns an error if any option fails validation (duplicate names, conflicts).
type CompilerOpt ¶
type CompilerOpt func(*compilerConfig) error
CompilerOpt configures a Compiler.
func ReplaceFunction ¶
func ReplaceFunction(name string, fn any) CompilerOpt
ReplaceFunction overrides a built-in function. Returns an error at compiler construction if the name is not a known built-in.
func WithFunction ¶
func WithFunction(name string, fn any) CompilerOpt
WithFunction registers a custom function available in all expressions compiled by this compiler. The function signature must be compatible with expr-lang's function binding.
Returns an error at compiler construction if:
- the name has already been registered
- the name conflicts with a built-in (use ReplaceFunction instead)
type EvalOpt ¶
type EvalOpt func(*evalConfig)
EvalOpt configures a single Eval call.
func WithEvalTrace ¶
WithEvalTrace writes evaluation trace output to w.
type MatchOpt ¶
type MatchOpt func(*matchConfig)
MatchOpt configures a single Match call.
func WithMatchTrace ¶
WithMatchTrace writes evaluation trace output to w.
type Program ¶
type Program[T any] struct { // contains filtered or unexported fields }
Program is a compiled expression. It is immutable and safe for concurrent use. Programs are only produced by Compiler.Compile.
func (*Program[T]) Match ¶
Match evaluates the expression against env and returns true/false. Returns ErrTypeMismatch if the expression does not return a bool.
type Source ¶
type Source struct {
// contains filtered or unexported fields
}
Source is the input to compilation. It pairs a name with an expression.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package rules is a typed rule evaluation engine built on anyexpr.
|
Package rules is a typed rule evaluation engine built on anyexpr. |
|
dispatch
Package dispatch routes evaluation results to named handler functions.
|
Package dispatch routes evaluation results to named handler functions. |