Struct EnvBuilder

Source
pub struct EnvBuilder<'f, Fm: FnMarker = (), Rm: RuntimeMarker = ()> { /* private fields */ }
Expand description

Builder for creating CEL environments.

The EnvBuilder allows you to configure a CEL environment by registering functions, declaring variables, and setting up runtime options before building the final environment.

§Type Parameters

  • 'f: Lifetime of functions that will be registered
  • Fm: Function marker type indicating sync/async function support
  • Rm: Runtime marker type indicating the async runtime (if any)

§Examples

use cel_cxx::*;

let env = Env::builder()
    .register_global_function("double", |x: i64| -> i64 { x * 2 })?
    .declare_variable::<String>("message")?
    .build()?;

Implementations§

Source§

impl<'f, Fm: FnMarker, Rm: RuntimeMarker> EnvBuilder<'f, Fm, Rm>

Source

pub fn new() -> Self

Creates a new environment builder.

§Examples
use cel_cxx::*;

let builder = EnvBuilder::<()>::new();
Source§

impl<'f, Fm: FnMarker, Rm: RuntimeMarker> EnvBuilder<'f, Fm, Rm>

Source

pub fn register_function<F, Ffm, Args>( self, name: impl Into<String>, member: bool, f: F, ) -> Result<EnvBuilder<'f, <Ffm as FnMarkerAggr<Fm>>::Output, Rm>, Error>
where F: IntoFunction<'f, Ffm, Args>, Ffm: FnMarker + FnMarkerAggr<Fm>, Args: Arguments,

Registers a function (either global or member).

This method allows you to register custom functions that can be called from CEL expressions. The function can be either a global function or a member function of a type.

§Function Registration Process

When you register a function, the system:

  1. Extracts type information from the function signature
  2. Creates type-safe conversion wrappers
  3. Stores both the type signature and implementation
  4. Updates the function marker type to track sync/async status
§Zero-Annotation Benefits

Functions are registered without explicit type annotations:

  • Argument types are automatically inferred
  • Return types are automatically determined
  • Error handling is automatically supported for Result<T, E> returns
  • Reference parameters like &str are handled safely
§Arguments
  • name - The name of the function as it will appear in CEL expressions
  • member - Whether this is a member function (true) or global function (false)
  • f - The function implementation (function pointer, closure, etc.)
§Type Parameters
  • F - The function implementation type
  • Ffm - The function marker type (sync/async) inferred from the function
  • Args - The argument tuple type (automatically inferred)
§Returns

A new EnvBuilder with updated function marker type. If this is the first async function registered, the marker changes from () to Async.

§Member vs Global Functions
§Global Functions

Called as function_name(args...):

max(a, b)           // max function with two arguments
calculate(x, y, z)  // calculate function with three arguments
§Member Functions

Called as object.method(args...):

text.contains(substring)    // contains method on string
list.size()                // size method on list
§Function Signature Support

Supports various function signatures:

  • Simple functions: fn(T) -> U
  • Functions with errors: fn(T) -> Result<U, E>
  • Reference parameters: fn(&str, i64) -> String
  • Multiple parameters: Up to 10 parameters supported
  • Closures: Move closures that capture environment
§Errors

Returns Error if:

  • Function name conflicts with existing registration
  • Function signature is invalid or unsupported
  • Type inference fails
§Examples
§Basic Functions
use cel_cxx::*;

let builder = Env::builder()
    .register_function("add", false, |a: i64, b: i64| a + b)?
    .register_function("greet", false, |name: &str| format!("Hello, {}!", name))?;
§Member Functions
use cel_cxx::*;

let builder = Env::builder()
    .register_function("contains", true, |text: &str, substr: &str| text.contains(substr))?
    .register_function("length", true, |text: &str| text.len() as i64)?;

// Usage in expressions:
// text.contains("hello")
// text.length()
§Functions with Error Handling
use cel_cxx::*;

let builder = Env::builder()
    .register_function("divide", false, |a: f64, b: f64| -> Result<f64, Error> {
        if b == 0.0 {
            Err(Error::invalid_argument("division by zero"))
        } else {
            Ok(a / b)
        }
    })?;
§Closures with Captured Data
use cel_cxx::*;

let multiplier = 5;
let threshold = 100.0;

let builder = Env::builder()
    .register_function("scale", false, move |x: i64| x * multiplier)?
    .register_function("check_limit", false, move |value: f64| value < threshold)?;
Source

pub fn register_member_function<F, Ffm, Args>( self, name: impl Into<String>, f: F, ) -> Result<EnvBuilder<'f, <Ffm as FnMarkerAggr<Fm>>::Output, Rm>, Error>
where F: IntoFunction<'f, Ffm, Args>, Ffm: FnMarker + FnMarkerAggr<Fm>, Args: Arguments,

Registers a member function.

This is a convenience method for registering member functions, equivalent to calling register_function(name, true, f). Member functions are called using dot notation in CEL expressions: object.method(args...).

§Arguments
  • name - The method name as it will appear in CEL expressions
  • f - The function implementation
§Member Function Semantics

Member functions in CEL follow these patterns:

  • First parameter is the “receiver” (the object before the dot)
  • Additional parameters become method arguments
  • Called as receiver.method(arg1, arg2, ...)
§Examples
§String Methods
use cel_cxx::*;

let builder = Env::builder()
    .register_member_function("upper", |s: &str| s.to_uppercase())?
    .register_member_function("contains", |s: &str, substr: &str| s.contains(substr))?
    .register_member_function("repeat", |s: &str, n: i64| s.repeat(n as usize))?;

// Usage in expressions:
// "hello".upper()           -> "HELLO"
// "hello world".contains("world") -> true
// "abc".repeat(3)           -> "abcabcabc"
§Numeric Methods
use cel_cxx::*;

let builder = Env::builder()
    .register_member_function("abs", |x: f64| x.abs())?
    .register_member_function("pow", |x: f64, exp: f64| x.powf(exp))?;

// Usage in expressions:
// (-5.5).abs()     -> 5.5
// (2.0).pow(3.0)   -> 8.0
Source

pub fn register_global_function<F, Ffm, Args>( self, name: impl Into<String>, f: F, ) -> Result<EnvBuilder<'f, <Ffm as FnMarkerAggr<Fm>>::Output, Rm>, Error>
where F: IntoFunction<'f, Ffm, Args>, Ffm: FnMarker + FnMarkerAggr<Fm>, Args: Arguments,

Registers a global function.

This is a convenience method for registering global functions, equivalent to calling register_function(name, false, f). Global functions are called directly by name in CEL expressions: function_name(args...).

§Arguments
  • name - The function name as it will appear in CEL expressions
  • f - The function implementation
§Global Function Characteristics

Global functions:

  • Are called directly by name without a receiver object
  • Can have 0 to 10 parameters
  • Support all CEL-compatible parameter and return types
  • Can capture environment variables (for closures)
§Function Naming Guidelines
  • Use clear, descriptive names: calculate_tax, format_date
  • Follow CEL naming conventions (snake_case is recommended)
  • Avoid conflicts with built-in CEL functions
  • Consider namespacing for domain-specific functions: math_sqrt, string_trim
§Examples
§Mathematical Functions
use cel_cxx::*;

let builder = Env::builder()
    .register_global_function("add", |a: i64, b: i64| a + b)?
    .register_global_function("multiply", |a: f64, b: f64| a * b)?
    .register_global_function("max", |a: i64, b: i64| if a > b { a } else { b })?;

// Usage in expressions:
// add(10, 20)          -> 30
// multiply(2.5, 4.0)   -> 10.0
// max(15, 8)           -> 15
§String Processing Functions
use cel_cxx::*;

let builder = Env::builder()
    .register_global_function("concat", |a: &str, b: &str| format!("{}{}", a, b))?
    .register_global_function("trim_prefix", |s: &str, prefix: &str| {
        s.strip_prefix(prefix).unwrap_or(s).to_string()
    })?;

// Usage in expressions:
// concat("Hello, ", "World!")     -> "Hello, World!"
// trim_prefix("prefixed_text", "prefixed_")  -> "text"
§Business Logic Functions
use cel_cxx::*;

let builder = Env::builder()
    .register_global_function("calculate_discount", |price: f64, rate: f64| {
        price * (1.0 - rate.min(1.0).max(0.0))
    })?
    .register_global_function("is_valid_email", |email: &str| {
        email.contains('@') && email.contains('.')
    })?;

// Usage in expressions:
// calculate_discount(100.0, 0.15)     -> 85.0
// is_valid_email("user@domain.com")   -> true
§Functions with Complex Logic
use cel_cxx::*;
use std::collections::HashMap;

// Function that processes collections
let builder = Env::builder()
    .register_global_function("sum_positive", |numbers: Vec<i64>| {
        numbers.iter().filter(|&x| *x > 0).sum::<i64>()
    })?;

// Usage in expressions:
// sum_positive([1, -2, 3, -4, 5])  -> 9
Source

pub fn declare_function<D>( self, name: impl Into<String>, member: bool, ) -> Result<Self, Error>
where D: FunctionDecl,

Declares a function signature without providing an implementation.

This is useful when you want to declare that a function exists for type checking purposes, but will provide the implementation later via activation bindings.

§Arguments
  • name - The name of the function
  • member - Whether this is a member function (true) or global function (false)
§Type Parameters
  • D - The function declaration type that specifies the signature
Source

pub fn declare_member_function<D>( self, name: impl Into<String>, ) -> Result<Self, Error>
where D: FunctionDecl,

Declares a member function signature without providing an implementation.

§Arguments
  • name - The name of the member function
§Type Parameters
  • D - The function declaration type that specifies the signature
Source

pub fn declare_global_function<D>( self, name: impl Into<String>, ) -> Result<Self, Error>
where D: FunctionDecl,

Declares a global function signature without providing an implementation.

§Arguments
  • name - The name of the global function
§Type Parameters
  • D - The function declaration type that specifies the signature
Source

pub fn define_constant<T>( self, name: impl Into<String>, value: T, ) -> Result<Self, Error>
where T: IntoConstant,

Defines a constant value that can be referenced in expressions.

Constants are immutable values that are resolved at compile time.

§Arguments
  • name - The name of the constant
  • value - The constant value
§Examples
use cel_cxx::*;

let builder = Env::builder()
    .define_constant("PI", 3.14159)
    .unwrap();
Source

pub fn declare_variable<T>(self, name: impl Into<String>) -> Result<Self, Error>
where T: TypedValue,

Declares a variable of a specific type.

This declares that a variable of the given name and type may be provided during evaluation. The actual value must be bound in the activation when evaluating expressions.

§Arguments
  • name - The name of the variable
§Type Parameters
  • T - The type of the variable
§Examples
use cel_cxx::*;

let builder = Env::builder()
    .declare_variable::<String>("user_name")?
    .declare_variable::<i64>("age")?;
Source

pub fn build(self) -> Result<Env<'f, Fm, Rm>, Error>

Builds the environment from the configured builder.

This method consumes the builder and creates the final Env instance that can be used to compile CEL expressions.

§Returns

Returns a Result containing the built Env or an Error if the environment could not be created.

§Examples
use cel_cxx::*;

let env = Env::builder()
    .declare_variable::<String>("name")?
    .build()?;
§Errors

Returns an error if the environment configuration is invalid or if the underlying CEL environment cannot be created.

Source§

impl<'f, Rm: RuntimeMarker> EnvBuilder<'f, (), Rm>

Source

pub fn force_async(self) -> EnvBuilder<'f, Async, Rm>

Available on crate feature async only.

Forces conversion to an async environment builder.

This method converts a synchronous environment builder to an asynchronous one, allowing it to register async functions and build async environments.

§Examples
use cel_cxx::*;

let async_builder = Env::builder().force_async();
Source§

impl<'f, Fm: FnMarker> EnvBuilder<'f, Fm, ()>

Source

pub fn use_runtime<Rt: Runtime>(self) -> EnvBuilder<'f, Fm, Rt>

Available on crate feature async only.

Sets the async runtime for the environment builder.

This method specifies which async runtime should be used by environments built from this builder.

§Type Parameters
  • Rt - The runtime type to use (must implement Runtime)
§Examples
use cel_cxx::*;

let builder = Env::builder().use_runtime::<Tokio>();
Source

pub fn use_tokio(self) -> EnvBuilder<'f, Fm, Tokio>

Available on crate features async and tokio only.

Configures the builder to use the Tokio async runtime.

This is a convenience method for setting the runtime to Tokio. Requires the tokio feature to be enabled.

§Examples
use cel_cxx::*;

let builder = Env::builder().use_tokio();
Source

pub fn use_async_std(self) -> EnvBuilder<'f, Fm, AsyncStd>

Available on crate features async and async-std only.

Configures the builder to use the async-std runtime.

This is a convenience method for setting the runtime to async-std. Requires the async-std feature to be enabled.

§Examples
use cel_cxx::*;

let builder = Env::builder().use_async_std();

Trait Implementations§

Source§

impl<'f, Fm: FnMarker, Rm: RuntimeMarker> Debug for EnvBuilder<'f, Fm, Rm>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'f, Fm: FnMarker, Rm: RuntimeMarker> Default for EnvBuilder<'f, Fm, Rm>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'f, Fm, Rm> Freeze for EnvBuilder<'f, Fm, Rm>

§

impl<'f, Fm = (), Rm = ()> !RefUnwindSafe for EnvBuilder<'f, Fm, Rm>

§

impl<'f, Fm, Rm> Send for EnvBuilder<'f, Fm, Rm>
where Fm: Send, Rm: Send,

§

impl<'f, Fm, Rm> Sync for EnvBuilder<'f, Fm, Rm>
where Fm: Sync, Rm: Sync,

§

impl<'f, Fm, Rm> Unpin for EnvBuilder<'f, Fm, Rm>
where Fm: Unpin, Rm: Unpin,

§

impl<'f, Fm = (), Rm = ()> !UnwindSafe for EnvBuilder<'f, Fm, Rm>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more