fsm-guards
Fuel-metered JSONLogic guard evaluation for FSM transition engines.
A fork of jsonlogic-rs v0.5, extended with:
- In-loop fuel metering — node-visit budget that short-circuits correctly:
{"or": [true, huge_branch]}withfuel: 10costs 2 nodes, not 1000. - Typed error classification —
GuardErrorwith five distinct variants replacing stringly-typed errors. - Per-evaluation custom operators — register extension functions on
EvalCtxfor each call; no global state.
Install
[]
= "0.1"
Quick start
use ;
use json;
let ctx = new
.with_fuel
.with_op;
let rule = json!;
let data = json!;
assert!;
API
evaluate — guard tier
- Pre-walks for
{"var": "X"}references whose root key is absent fromdata→GuardError::MissingVar. - Runs the evaluator with
ctx.fuelas the node budget. - Coerces the result to
bool(JSONLogic truthy: null/false/0/""/[] → false).
apply — raw tier
No fuel limit. No custom operators. Returns the raw JSONLogic result value.
EvalCtx
let ctx = new // fuel: 200, no custom ops
.with_fuel
.with_op;
EvalCtx is Send + Sync. Wrap in Arc to share across threads; each evaluate call uses its own stack-local fuel counter.
Error variants
| Variant | Meaning |
|---|---|
GuardError::Malformed(msg) |
Structural AST problem or unknown operator |
GuardError::MissingVar(path) |
{"var": "X"} where root key absent from data |
GuardError::TypeError(msg) |
Type coercion or argument-arity error |
GuardError::FuelExceeded { limit } |
Node budget exhausted |
GuardError::CustomOpFailed { op, source } |
Registered operator returned Err |
Fuel accounting
Fuel is decremented for every node visit — literals, operators, all values. Short-circuit operators charge only for visited branches:
{"or": [true, <200-node-branch>]} with fuel:10 → Ok(true) // 2 nodes visited
{"or": [false, {"==": [1,1]}]} with fuel:10 → Ok(true) // 3 nodes visited
Default: 200 nodes. FastYoke's production limit: 50 nodes for trigger predicates, 200 for guard rules.
JSONLogic compatibility
Passes 273/278 of the JSONLogic test suite. The 5 failures are inherited jsonlogic-rs v0.5 limitations:
- Array literals containing
{"var": "..."}— vars inside array literals are not recursively evaluated ?:ternary operator — not implementedmissingwith an expression argument — does not pre-evaluate its argument
License
MIT. Forked from jsonlogic-rs v0.5 by Bestow Inc.