pub struct Logic { /* private fields */ }Expand description
Compiled logic that can be evaluated multiple times across different data.
Logic represents a pre-processed JSONLogic expression that has been
optimized for repeated evaluation. It’s thread-safe and can be shared across
threads using Arc.
§Performance Benefits
- Parse once, evaluate many: Avoid repeated JSON parsing
- Static evaluation: Constant expressions are pre-computed
- OpCode dispatch: Built-in operators use fast enum dispatch
- Thread-safe sharing: Use
Arcto share across threads
§Example
use std::sync::Arc;
use datalogic_rs::Engine;
let engine = Engine::new();
let compiled = Arc::new(engine.compile(r#"{">": [{"var": "score"}, 90]}"#).unwrap());
// Compiled logic can be cloned cheaply (atomic refcount) and sent across threads.
let compiled_clone = Arc::clone(&compiled);
std::thread::spawn(move || {
let engine = Engine::new();
let _result = engine
.session()
.eval_str(&compiled_clone, r#"{"score": 95}"#)
.unwrap();
});Logic is Clone (deep-clones the compiled tree). Cloning is the right
choice when a caller needs an independently mutable copy or wants to
store the rule by value; for sharing the same compiled rule across
threads or evaluations, prefer Arc<Logic> — the Arc::clone is a
single atomic refcount bump rather than a tree walk.
Implementations§
Source§impl Logic
impl Logic
Sourcepub fn is_static(&self) -> bool
pub fn is_static(&self) -> bool
Check if this compiled logic is static (can be evaluated without context)
Sourcepub fn to_json(&self) -> String
pub fn to_json(&self) -> String
Reconstruct a JSONLogic string from this compiled tree.
Reflects the compiled shape — constant-folded sub-expressions
appear as literals, since the original operator is gone by then.
Re-parsing the output through crate::Engine::compile yields a
Logic that evaluates identically. Useful for caching keys, identity
checks across compiled rules, debug logging, and tooling.
Var nodes serialise to {"var": "..."} for scope_level == 0
and to {"val": [[<level>], ...]} for scope_level > 0 — that’s
the shape the compiler accepts on round-trip.
§Example
use datalogic_rs::Engine;
let engine = Engine::new();
let compiled = engine.compile(r#"{">": [{"var": "score"}, 90]}"#).unwrap();
let json = compiled.to_json();
assert!(json.contains(r#""var": "score""#));
// Round-trip: re-compiling the output produces an equivalent rule.
let recompiled = engine.compile(&json).unwrap();
assert_eq!(
engine.eval_str(&json, r#"{"score": 95}"#).unwrap(),
"true",
);Source§impl Logic
impl Logic
Sourcepub fn resolve_node_ids(&self, ids: &[u32]) -> Vec<PathStep>
pub fn resolve_node_ids(&self, ids: &[u32]) -> Vec<PathStep>
Translate a breadcrumb of compiled-node ids into structured
PathSteps, root-to-leaf.
Input is the leaf-to-root breadcrumb stored on crate::Error::node_ids.
Walks the compiled tree once to build an id → location index, then
resolves each input id; ids absent from the tree are skipped (defensive
against synthetic nodes from operator fast paths).