Public API and Engine

The full public surface of the jetro crate is two types and a handful of methods. Everything else is implementation detail.

Jetro — single-document handle

For one document, possibly many queries:

use jetro::Jetro;

let bytes = br#"{"x":[1,2,3]}"#;
let j = Jetro::from_bytes(bytes)?;          // lazy parse via simd-json tape
let v: serde_json::Value = j.collect("$.x.sum()")?;
assert_eq!(v, serde_json::json!(6));

Constructors

MethodInputNotes
Jetro::from_bytes(&[u8])Raw JSON bytesLazy parse — fastest path
Jetro::from_value(serde_json::Value)Parsed valueSkip simd-json
Jetro::from_val(Val)Internal ValAdvanced — re-using engine state

Methods

MethodReturns
j.collect(query)Result<serde_json::Value, EvalError>
j.collect_typed::<T>(query)Result<T, EvalError> (deserialize directly)

Jetro owns its per-document lazy state: raw bytes, tape/value caches, object vector promotion cache, and an instance VM used for fallback execution. It is cheap to construct for a document and can answer many queries over the same bytes without reparsing.

JetroEngine — long-lived multi-doc handle

For many documents and many queries with overlap, share the plan/VM caches:

use jetro::JetroEngine;

let eng = JetroEngine::default();

for doc_bytes in inputs {
    let v = eng.collect_bytes(doc_bytes, "$.users.filter(@.active).count()")?;
    println!("{}", v);
}

Methods

MethodInputNotes
eng.collect(&doc, q)&ValDocument already in Val form
eng.collect_value(serde_value, q)serde_json::ValueRound-trips
eng.collect_bytes(&[u8], q)Raw bytesLazy parse
eng.run_ndjson(...)Reader, query, writerRow-local NDJSON execution
eng.run_ndjson_file(...)File path, query, writerFile-backed NDJSON, including $.rows() stream mode
eng.run_ndjson_source(...)Reader or file sourceDispatches reader/file behavior explicitly

Returns Result<serde_json::Value, JetroEngineError> — a wider error type that may also wrap JSON-parse errors.

NDJSON options

NDJSON helpers accept NdjsonOptions variants for file and reader workloads:

OptionEffect
row_framePlain JSON lines or delimited payloads such as `key
null_outputSkip or emit expression results that are JSON null
parallelismAutomatic or disabled partition execution for eligible file streams
parallel_min_bytesMinimum file size before parallel partitions are considered
max_line_lenPer-line safety cap
reverse_chunk_sizeReverse file-reader chunk size

Expression-level $.rows() switches NDJSON from row-local execution to a whole-source stream plan. On files, $.rows().reverse() uses reverse file traversal; reader-backed reverse streams return a clear unsupported-source error.

Configuration

OptionDefaultEffect
Plan-cache capacity256Wholesale-evicted when full

The engine's plan cache amortises parse + lower + compile across calls. Hits are O(hash); misses do full work.

Errors

pub enum EvalError {
    /* … */
}

pub enum JetroEngineError {
    Json(serde_json::Error),
    Eval(EvalError),
}

Error messages include the query position when available.

Feature flags

FeatureDefaultWhat it does
simd-jsononDirect bytes → Val parse, skipping serde_json::Value
fuzz_internaloffRe-exports parser + planner for fuzz harness — not stable

To disable simd-json:

[dependencies]
jetro = { version = "0.5.11", default-features = false }

Python binding

jetro_py exposes a collect(doc, query) function. Internals are identical to the Rust crate.

import jetro

result = jetro.collect({"x": [1,2,3]}, "$.x.sum()")
# result == 6

CLI

jetrocli -e '$.x.sum()' < input.json
jetrocli --ndjson -i events.ndjson -e '$.rows().take(10)'

The CLI is a thin wrapper around the Rust APIs, with -e selecting non-interactive expression execution.

Threading

  • Jetro is intended as a document handle. Prefer one handle per document owner; use JetroEngine for shared multi-document workloads.
  • JetroEngine is Send + Sync and intended for shared-engine workloads.
  • The engine owns shared plan/VM caches so repeated queries over many documents avoid parse/lower/compile cost.

Stability

  • The query DSL is stable as of jetro 0.5.x.
  • The Rust API surface (Jetro, JetroEngine, error types) is stable.
  • BuiltinMethod, opcodes, IR types are internal and may change in any minor release.
  • The fuzz_internal feature is explicitly unstable.