cel-cxx 0.2.5

A high-performance, type-safe Rust interface for Common Expression Language (CEL), build on top of cel-cpp with zero-cost FFI bindings via cxx
Documentation
use super::{MacroExprFactory, Expr};

/// Trait for global macro expansion functions.
///
/// A global macro expander receives a list of arguments and produces a transformed
/// expression. Global macros are triggered by function calls, not method calls.
///
/// # Type Requirements
///
/// The expander function must be:
/// - `Fn(&mut MacroExprFactory, Vec<Expr>) -> Option<Expr>`: The expansion signature
/// - `Send + Sync`: Thread-safe for use in concurrent environments
/// - `'static`: No borrowed references in the closure
///
/// # Return Value
///
/// - `Some(expr)`: The macro expansion succeeded and `expr` replaces the original call
/// - `None`: The macro cannot be expanded (keeps the original expression)
///
/// # Examples
///
/// ```rust,no_run
/// # use cel_cxx::macros::{GlobalMacroExpander, MacroExprFactory, Expr};
/// # use cel_cxx::Constant;
/// // Simple constant-folding macro
/// fn optimize_add(factory: &mut MacroExprFactory, args: Vec<Expr>) -> Option<Expr> {
///     if args.len() != 2 {
///         return None;
///     }
///
///     // If both args are constant integers, fold them
///     let left = match args[0].kind()?.as_constant()? { Constant::Int(n) => *n, _ => return None };
///     let right = match args[1].kind()?.as_constant()? { Constant::Int(n) => *n, _ => return None };
///
///     Some(factory.new_const(left + right))
/// }
/// ```
pub trait GlobalMacroExpander
    : Fn(&MacroExprFactory<'_>, Vec<Expr>) -> Option<Expr> + Send + Sync
{}

impl<'f, F> GlobalMacroExpander for F where F
    : Fn(&MacroExprFactory<'_>, Vec<Expr>) -> Option<Expr> + Send + Sync
    + 'f
{}

/// Trait for receiver macro expansion functions.
///
/// A receiver macro expander receives a target expression and a list of arguments,
/// then produces a transformed expression. Receiver macros are triggered by method
/// calls on a target object.
///
/// # Type Requirements
///
/// The expander function must be:
/// - `Fn(&mut MacroExprFactory, Expr, Vec<Expr>) -> Option<Expr>`: The expansion signature
/// - `Send + Sync`: Thread-safe for use in concurrent environments
/// - `'static`: No borrowed references in the closure
///
/// # Parameters
///
/// - `factory`: Factory for creating new expression nodes
/// - `target`: The receiver expression (the object before the dot)
/// - `args`: The argument list passed to the method
///
/// # Return Value
///
/// - `Some(expr)`: The macro expansion succeeded and `expr` replaces the original call
/// - `None`: The macro cannot be expanded (keeps the original expression)
///
/// # Examples
///
/// ```rust,no_run
/// # use cel_cxx::macros::{ReceiverMacroExpander, MacroExprFactory, Expr};
/// // Macro for optional chaining: target.get_or(default)
/// fn get_or_macro(
///     factory: &mut MacroExprFactory,
///     target: Expr,
///     mut args: Vec<Expr>
/// ) -> Option<Expr> {
///     if args.len() != 1 {
///         return None;
///     }
///     
///     let default_value = args.pop()?;
///     
///     // Expand to: target != null ? target : default_value
///     let target_copy = factory.copy_expr(&target);
///     Some(factory.new_call("_?_:_", &[
///         factory.new_call("_!=_", &[target_copy, factory.new_const(())]),
///         target,
///         default_value,
///     ]))
/// }
/// ```
pub trait ReceiverMacroExpander
    : Fn(&MacroExprFactory<'_>, Expr, Vec<Expr>) -> Option<Expr> + Send + Sync
{}

impl<'f, F> ReceiverMacroExpander for F where F
    : Fn(&MacroExprFactory<'_>, Expr, Vec<Expr>) -> Option<Expr> + Send + Sync
    + 'f
{}