pub trait CustomOperator: Send + Sync {
// Required method
fn evaluate<'a>(
&self,
args: &[&'a DataValue<'a>],
ctx: &mut EvalContext<'_, 'a>,
arena: &'a Bump,
) -> Result<&'a DataValue<'a>>;
}Expand description
Custom operator hook for the Engine.
Implementations receive args already evaluated as borrowed
DataValue references and return a &'a DataValue<'a> result
allocated in the supplied bumpalo::Bump arena.
§Lifetime
'a is the arena lifetime, tied to the bumpalo::Bump allocator
that lives for the duration of one Engine::evaluate call. Args
borrow from the caller’s input and from prior arena allocations; the
returned &'a DataValue<'a> must be allocated in the arena (or be a
preallocated singleton) — never a stack reference.
§Example
use datalogic_rs::{CustomOperator, DataValue, Engine, Result, operator::EvalContext};
use bumpalo::Bump;
struct DoubleArena;
impl CustomOperator for DoubleArena {
fn evaluate<'a>(
&self,
args: &[&'a DataValue<'a>],
_ctx: &mut EvalContext<'_, 'a>,
arena: &'a Bump,
) -> Result<&'a DataValue<'a>> {
let n = args.first().and_then(|v| v.as_f64()).unwrap_or(0.0);
Ok(arena.alloc(DataValue::from_f64(n * 2.0)))
}
}
let engine = Engine::builder().add_operator("double", DoubleArena).build();
let result = engine.eval_str(r#"{"double": 21}"#, "null").unwrap();
assert_eq!(result, "42");§Stability
This trait is the headline extension point of the crate and is
intentionally not sealed. Within the 5.x series the only changes
that will be made to this trait are default-method additions — no
new required methods, no signature changes to Self::evaluate, no
lifetime restructuring. Implementations written against 5.0 will
compile against every 5.x release without modification. Any breaking
change here requires a 6.0 bump.
The opaque types in the signature (crate::DataValue,
operator::EvalContext, bumpalo::Bump) may evolve internally
without breaking this contract, since their public surface is the
stable boundary.
Required Methods§
Sourcefn evaluate<'a>(
&self,
args: &[&'a DataValue<'a>],
ctx: &mut EvalContext<'_, 'a>,
arena: &'a Bump,
) -> Result<&'a DataValue<'a>>
fn evaluate<'a>( &self, args: &[&'a DataValue<'a>], ctx: &mut EvalContext<'_, 'a>, arena: &'a Bump, ) -> Result<&'a DataValue<'a>>
Evaluate this operator with arena-allocated args and result.
§Arguments
args— pre-evaluated args as&'a DataValue<'a>. The arena dispatcher has already recursed into each arg’s expression tree.ctx— opaque view into the engine’s evaluation context. Most operators ignore this; it exposesoperator::EvalContext::root_inputandoperator::EvalContext::depthfor the rare case where an operator’s behaviour depends on the surrounding context.arena— thebumpalo::Bumpallocator. Usearena.alloc(...)for arena values,arena.alloc_str(...)for strings. For the common case of returning a typedDataValueresult, prefer the one-call helpers onArenaExt(arena.f64(n),arena.string(s),arena.bool(b), …) — they are zero-cost over the manual form and short-circuit to preallocated singletons fornull, booleans, small ints, and empty string/array/object.