Documentation
¶
Overview ¶
Package expr provides rlng's atomic expression evaluators, built on github.com/expr-lang/expr.
Predicate compiles a boolean expression; by default it is strict (the result must be a bool) and returns an EvalError wrapping ErrNotBool otherwise. Pass WithCoerce for lenient truthiness.
Function compiles a value-producing expression with an optional WithFallback expression. By default the fallback fires only when the main expression errors; a nil main result is returned as-is. WithFallbackOnNil restores the fallback-on-nil behavior, and WithFallbackObserver surfaces the error the fallback would otherwise mask.
Both accept an environment that is either a map[string]any or a struct (converted field-by-field), and both support WithGlobals/WithLocals default variables injected as `x ?? <default>` at compile time. All failures are *CompileError or *EvalError, which name the field and expression and unwrap to the underlying cause.
WithCoerce enables lenient truthiness on Predicate: numbers are true iff non-zero and finite (NaN/±Inf are false), strings follow strconv.ParseBool for recognized bool spellings and otherwise non-empty-after-trim, and an unhandled result type returns an *EvalError instead of a silent false.
Index ¶
- Variables
- type CompileError
- type EvalError
- type Function
- type Option
- func WithCoerce() Option
- func WithEnv(env map[string]any) Option
- func WithFallback(expression string) Option
- func WithFallbackObserver(fn func(name, expression string, cause error)) Option
- func WithFallbackOnNil() Option
- func WithFunction(name string, fn func(...any) (any, error)) Option
- func WithGlobals(vars map[string]any) Option
- func WithLocals(vars map[string]any) Option
- func WithReturnKind(k reflect.Kind) Option
- type Predicate
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrEmptyExpression = errors.New("expression must not be empty")
ErrEmptyExpression is returned (wrapped in a CompileError) when an empty or whitespace-only expression is supplied to NewPredicate/NewFunction.
var ErrEnvTooDeep = fmt.Errorf("env exceeds max nesting depth %d (possible cyclic reference)", maxEnvDepth)
ErrEnvTooDeep is returned (wrapped in an EvalError) when an env's struct/map/ slice nesting exceeds maxEnvDepth, e.g. a struct with a self-referential pointer. It is a bounded error rather than a process-crashing stack overflow.
var ErrNotBool = errors.New("expression did not evaluate to bool")
ErrNotBool is returned (wrapped in an EvalError) when a strict Predicate's expression evaluates to a non-boolean value.
Functions ¶
This section is empty.
Types ¶
type CompileError ¶
CompileError reports a failure to compile an expression. It names the field (if any) and the offending expression, and unwraps to the underlying cause.
func (*CompileError) Error ¶
func (e *CompileError) Error() string
Error renders `compile "name" (expression): <cause>`, omitting the cause suffix when Cause is nil.
func (*CompileError) Unwrap ¶
func (e *CompileError) Unwrap() error
Unwrap returns the underlying compilation cause for errors.Is/As.
type EvalError ¶
EvalError reports a failure while evaluating a compiled expression. It names the field (if any) and the expression, and unwraps to the underlying cause.
type Function ¶
type Function struct {
// contains filtered or unexported fields
}
Function is a compiled value-producing expression with an optional fallback. It is safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/kartaladev/rlng/expr"
)
func main() {
f, err := expr.NewFunction("total", "price * qty")
if err != nil {
fmt.Println("error:", err)
return
}
got, _ := f.Apply(map[string]any{"price": 10, "qty": 3})
fmt.Println(got)
}
Output: 30
func NewFunction ¶
NewFunction compiles expression into a named Function. When WithFallback is given, the fallback expression is compiled now (its compile errors surface from NewFunction, not from Apply) and evaluated, over an empty env, whenever Apply's main expression errors — and, with WithFallbackOnNil, also when it yields nil (nil is first-class by default). WithReturnKind compiles the main expression to coerce its result to the given kind.
func (*Function) Apply ¶
Apply evaluates the function against env (a map[string]any or a struct). If the main expression errors and a fallback was configured via WithFallback, the fallback is evaluated (over an empty env) and its result returned instead; when a WithFallbackObserver was registered, it is called with the masked error before the fallback runs. A nil main result is returned as-is by default — nil is first-class — unless WithFallbackOnNil was set, in which case a nil result also triggers the fallback (without invoking the observer, since there is no error to report).
func (*Function) References ¶
References returns the sorted, unique paths this Function reads: the deepest statically-known member path per reference (e.g. "grade.tier"), or the bare identifier when the chain is not statically resolvable (dynamic/index access, method calls). Computed once at compile; used to record provenance inputs. The returned slice must not be mutated.
type Option ¶
type Option func(*config)
Option configures a Predicate or Function. Options that do not apply to a given evaluator are ignored: WithCoerce applies only to Predicate; WithFallback and WithReturnKind only to Function; WithGlobals/WithLocals to both.
func WithCoerce ¶
func WithCoerce() Option
WithCoerce makes a Predicate use lenient truthiness instead of the default strict (bool-only) mode.
func WithEnv ¶
WithEnv enables strict compilation against a declared environment: the expression is type-checked against env (a map of field name -> a representative value giving its type), and undefined-variable tolerance is dropped. A field typo such as `scoer` then fails at compile time instead of silently evaluating to nil. Declared globals/locals (WithGlobals/WithLocals) and registered functions (WithFunction) are merged into the type-check environment so they remain usable. Without WithEnv the default is lenient (undefined variables allowed), preserving prior behavior.
func WithFallback ¶
WithFallback sets a Function's fallback expression, evaluated (over an empty env) when the main expression errors (or, with WithFallbackOnNil, also when it yields nil).
func WithFallbackObserver ¶
WithFallbackObserver registers a callback invoked when a Function's fallback fires because the main expression ERRORED, receiving the function name, the main expression, and the triggering cause — so the masked error is observable rather than silently discarded. It is not called for a nil-triggered fallback.
func WithFallbackOnNil ¶
func WithFallbackOnNil() Option
WithFallbackOnNil makes a Function's fallback also fire when the main expression evaluates to nil (not only when it errors). By default nil is a first-class result and the fallback fires only on an error.
func WithFunction ¶
WithFunction registers a host function callable from the expression by name, e.g. WithFunction("now", ...) or a domain helper like businessDaysBetween. The function is visible to both the compiler (so it type-checks, including in WithEnv strict mode) and the VM. Registering the same name twice keeps the last registration.
func WithGlobals ¶
WithGlobals adds engine-wide default variables, injected as `??` defaults. Multiple calls merge (last value wins per key), so a pipeline-level constant and a per-expression global can coexist rather than the later call discarding the earlier keys.
func WithLocals ¶
WithLocals adds per-evaluator default variables; they take precedence over globals. Multiple calls merge (last value wins per key), as WithGlobals.
func WithReturnKind ¶
WithReturnKind compiles a Function to coerce its result to the given kind.
type Predicate ¶
type Predicate struct {
// contains filtered or unexported fields
}
Predicate is a compiled boolean expression. It is safe for concurrent use.
Example ¶
package main
import (
"fmt"
"github.com/kartaladev/rlng/expr"
)
func main() {
p, err := expr.NewPredicate("amount > threshold",
expr.WithGlobals(map[string]any{"threshold": 100}))
if err != nil {
fmt.Println("error:", err)
return
}
ok, _ := p.Test(map[string]any{"amount": 150})
fmt.Println(ok)
}
Output: true
func NewPredicate ¶
NewPredicate compiles expression into a Predicate. By default the expression must evaluate to a bool (strict); pass WithCoerce for lenient truthiness.
func (*Predicate) References ¶
References returns the sorted, unique paths this Predicate reads: the deepest statically-known member path per reference (e.g. "grade.tier"), or the bare identifier when the chain is not statically resolvable (dynamic/index access, method calls). Computed once at compile; used to record provenance inputs. The returned slice must not be mutated.