seuil
A complete, safe JSONata implementation in Rust — JSON query, transform, and expression evaluation.
Documentation | Crate | Repository | Changelog
Seuil (French: "threshold") is a JSONata query and transformation engine for Rust. Compile a JSONata expression once, then evaluate it against any JSON input — fast, safe, and spec-compliant.
use Seuil;
let expr = compile?;
let data = json!;
let result = expr.evaluate?;
assert_eq!;
Why seuil?
- 99.6% JSONata spec compliance — 1,027 of 1,031 official test cases pass
- Zero
unsafe—#![forbid(unsafe_code)]enforced at the crate level - Zero panics on any input — malformed expressions and data return
Err, never crash - Compile once, evaluate many — parse the expression once, run it against thousands of inputs
- Fast-path JSON input —
serde_json::Valueconverts directly to the arena, bypassing the expression parser - 47 built-in functions — strings, math, arrays, objects, higher-order functions, date/time, regex
- Arena allocation — all values in a bumpalo arena for cache-friendly, zero-fragmentation evaluation
- Deterministic simulation testing — injectable
Environmenttrait for fully reproducible evaluation
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
= "1"
API
use ;
// Compile a JSONata expression
let expr = compile?;
// Evaluate against serde_json::Value
let result = expr.evaluate?;
// Evaluate against a JSON string
let result = expr.evaluate_str?;
// Evaluate with no input
let result = compile?.evaluate_empty?;
// Evaluate with custom config (timeouts, depth limits)
let config = EvalConfig ;
let result = expr.evaluate_with_config?;
Built-in Functions
String
$string · $length · $substring · $substringBefore · $substringAfter · $uppercase · $lowercase · $trim · $pad · $contains · $split · $join · $replace · $match · $base64encode · $base64decode
Numeric
$number · $abs · $floor · $ceil · $round · $power · $sqrt · $random · $sum · $max · $min · $average
Array
$count · $append · $sort · $reverse · $shuffle · $distinct · $zip · $flatten
Object
$keys · $lookup · $spread · $merge · $sift · $each · $error · $assert · $type
Higher-Order
$map · $filter · $single · $reduce
Type & Logic
$boolean · $not · $exists
Date/Time
$now · $millis · $fromMillis · $toMillis
Deterministic Testing
All non-determinism ($now(), $millis(), $random(), $uuid()) is injectable via the Environment trait:
use MockEnvironment;
use EvalConfig;
let env = new;
let config = with_environment;
// Every evaluation with the same seed produces identical results.
Comparison
| Feature | seuil | jsonata-rs (Stedi) | jsonpath-rust | jmespath |
|---|---|---|---|---|
| Language | JSONata | JSONata | JSONPath | JMESPath |
| Spec compliance | 99.6% | ~68% (self-described "incomplete") | N/A | N/A |
| Unsafe code | forbid(unsafe_code) |
4 blocks (incl. UB) | Uses unsafe | No unsafe |
| Functions | 47 built-in | ~35 (14+ missing) | None | 50+ |
| Higher-order functions | Full ($map, $filter, $reduce) | Stubs for some | No | Limited |
| Expression compilation | Compile once, eval many | Per-evaluation parse | Per-evaluation | Compile + eval |
| Deterministic testing | MockEnvironment | None | None | None |
| Fuzz testing | libfuzzer + VOPR + chaos | None | None | None |
| Arena allocation | bumpalo | bumpalo | No | No |
Testing Rigor
seuil is tested beyond typical crate standards:
- Official test suite: 1,027 of 1,031 active JSONata test cases pass
- VOPR campaigns: 10,000+ seed verification with zero panics
- Chaos testing: 9 fault injection categories — truncation, deep nesting, huge arrays, Unicode stress, type confusion, malformed input, resource exhaustion
- Property-based testing: ~14,000 generated cases via proptest
- Coverage-guided fuzzing: libfuzzer with corpus and dictionary
- Continuous verification: GitHub Actions CI on every push, nightly fuzzing and VOPR campaigns
Use Cases
seuil was built for dental RPA and healthcare EDI processing at Zuub, where expressions evaluate thousands of eligibility responses, claims, and benefit structures:
use Seuil;
// Extract dental benefits from an eligibility response
let expr = compile?;
let max = expr.evaluate?;
// Get patient name
let name = compile?;
let full_name = name.evaluate?;
It works equally well for any JSON query and transformation task — API response processing, configuration extraction, data pipeline transforms, log analysis, and more.
Architecture
Expression String ──→ Parser (Pratt) ──→ AST ──→ Evaluator ──→ Result
│
┌──────────┴──────────┐
│ bumpalo Arena │
│ (all values here) │
│ ScopeStack │
│ 47 native functions │
│ Environment trait │
└─────────────────────┘
- Parser: Pratt parser with operator precedence, all JSONata operators including parent (
%) - Evaluator: Recursive AST walker with tail-call optimization trampoline
- Values: Arena-allocated via bumpalo — zero per-value heap allocation, cache-friendly layout
- Scope: Stack-based variable scoping with lambda capture snapshots (no
Rc<RefCell>) - Functions: 47 built-in functions with higher-order function callback wiring
Minimum Supported Rust Version
The MSRV is 1.77.0.
License
Licensed under the Apache License, Version 2.0.
Contributing
See CONTRIBUTING for development setup, running tests, benchmarks, VOPR campaigns, and the fuzzer.