expr

package
v0.0.0-...-a608423 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

View Source
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.

View Source
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.

View Source
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

type CompileError struct {
	Name       string
	Expression string
	Cause      error
}

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

type EvalError struct {
	Name       string
	Expression string
	Cause      error
}

EvalError reports a failure while evaluating a compiled expression. It names the field (if any) and the expression, and unwraps to the underlying cause.

func (*EvalError) Error

func (e *EvalError) Error() string

Error renders `eval "name" (expression): <cause>`, omitting the cause suffix when Cause is nil.

func (*EvalError) Unwrap

func (e *EvalError) Unwrap() error

Unwrap returns the underlying evaluation cause for errors.Is/As.

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

func NewFunction(name, expression string, opts ...Option) (*Function, error)

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

func (f *Function) Apply(env any) (any, error)

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

func (f *Function) References() []string

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.

func (*Function) Source

func (f *Function) Source() string

Source returns the Function's original (untrimmed) expression string.

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

func WithEnv(env map[string]any) Option

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

func WithFallback(expression string) Option

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

func WithFallbackObserver(fn func(name, expression string, cause error)) Option

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

func WithFunction(name string, fn func(...any) (any, error)) Option

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

func WithGlobals(vars map[string]any) Option

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

func WithLocals(vars map[string]any) Option

WithLocals adds per-evaluator default variables; they take precedence over globals. Multiple calls merge (last value wins per key), as WithGlobals.

func WithReturnKind

func WithReturnKind(k reflect.Kind) Option

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

func NewPredicate(expression string, opts ...Option) (*Predicate, error)

NewPredicate compiles expression into a Predicate. By default the expression must evaluate to a bool (strict); pass WithCoerce for lenient truthiness.

func (*Predicate) References

func (p *Predicate) References() []string

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.

func (*Predicate) Source

func (p *Predicate) Source() string

Source returns the Predicate's original (untrimmed) expression string.

func (*Predicate) Test

func (p *Predicate) Test(env any) (bool, error)

Test evaluates the predicate against env (a map[string]any or a struct).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL