Skip to main content

CustomOperator

Trait CustomOperator 

Source
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§

Source

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 exposes operator::EvalContext::root_input and operator::EvalContext::depth for the rare case where an operator’s behaviour depends on the surrounding context.
  • arena — the bumpalo::Bump allocator. Use arena.alloc(...) for arena values, arena.alloc_str(...) for strings. For the common case of returning a typed DataValue result, prefer the one-call helpers on ArenaExt (arena.f64(n), arena.string(s), arena.bool(b), …) — they are zero-cost over the manual form and short-circuit to preallocated singletons for null, booleans, small ints, and empty string/array/object.

Trait Implementations§

Source§

impl CustomOperator for Box<dyn CustomOperator>

Source§

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. Read more

Implementations on Foreign Types§

Source§

impl CustomOperator for Box<dyn CustomOperator>

Source§

fn evaluate<'a>( &self, args: &[&'a DataValue<'a>], ctx: &mut EvalContext<'_, 'a>, arena: &'a Bump, ) -> Result<&'a DataValue<'a>>

Implementors§