pub struct Function<'f> { /* private fields */ }
Expand description
A type-erased function implementation that can be called from CEL expressions.
This is the main type used to store and invoke registered functions. It provides a uniform interface for calling functions regardless of their original signature.
§Design
The Function
struct uses dynamic dispatch through trait objects to provide
a uniform interface while maintaining type safety. The original function’s
type information is preserved through internal trait implementations.
§Memory Safety
Despite using type erasure, the system maintains complete memory safety:
- All conversions are checked at runtime
- Lifetime relationships are preserved where possible
- Reference parameters are handled safely through controlled lifetime management
§Performance
- Function calls involve minimal overhead (one virtual call + conversions)
- Argument validation is performed once per call
- Type conversions use zero-copy where possible
§Examples
§Basic Usage
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
let func = greet.into_function();
let args = vec!["World".into()];
let result = func.call(args);
§Metadata Inspection
let func = greet.into_function();
// Inspect function signature
println!("Arguments: {:?}", func.arguments());
println!("Return type: {:?}", func.result());
println!("Function type: {:?}", func.function_type());
Implementations§
Source§impl<'f> Function<'f>
impl<'f> Function<'f>
Sourcepub fn call<'this, 'future>(
&'this self,
args: Vec<Value>,
) -> MaybeFuture<'future, Value, Error>where
Self: 'future,
'this: 'future,
pub fn call<'this, 'future>(
&'this self,
args: Vec<Value>,
) -> MaybeFuture<'future, Value, Error>where
Self: 'future,
'this: 'future,
Call the function with the provided arguments.
This method invokes the function with type-safe argument conversion
and return value handling. It supports both synchronous and asynchronous
functions through the MaybeFuture
return type.
§Arguments
args
- Vector ofValue
arguments to pass to the function
§Returns
Returns a MaybeFuture
that represents either an immediate result or a future:
- Without
async
feature:MaybeFuture
isResult<Value, Error>
- returns immediately - With
async
feature:MaybeFuture
can be either:MaybeFuture::Result(Result<Value, Error>)
for synchronous functionsMaybeFuture::Future(BoxFuture<Result<Value, Error>>)
for async functions
§Type Safety
The method performs runtime type checking to ensure:
- Correct number of arguments is provided
- Each argument can be converted to the expected parameter type
- Return value conversion succeeds
§Errors
Returns an Error
if:
- The number of arguments doesn’t match the function signature
- Argument types cannot be converted to the expected types
- The function itself returns an error
- Return value conversion fails
§Examples
§Synchronous function call
fn add(a: i64, b: i64) -> i64 { a + b }
let func = add.into_function();
let args = vec![Value::Int(10), Value::Int(20)];
let maybe_result = func.call(args);
// In sync mode, extract the result directly
let result = maybe_result.unwrap();
// In async mode, check if it's an immediate result
let result = maybe_result.expect_result("shoud be result")?;
assert_eq!(result, Value::Int(30));
§Async function call (when async
feature is enabled)
async fn async_multiply(a: i64, b: i64) -> i64 { a * b }
let func = async_multiply.into_function();
let args = vec![Value::Int(6), Value::Int(7)];
let maybe_result = func.call(args);
// For async functions, extract and await the future
let result = maybe_result.unwrap_future().await.unwrap();
assert_eq!(result, Value::Int(42));
Sourcepub fn arguments(&self) -> Vec<ValueType>
pub fn arguments(&self) -> Vec<ValueType>
Get the expected argument types for this function.
Returns the function signature information that can be used for:
- Compile-time type checking
- Runtime argument validation
- Documentation generation
- IDE support and auto-completion
§Returns
A vector of ValueType
representing the expected argument types
in the order they should be provided to call
.
§Examples
fn process(name: &str, count: i64, active: bool) -> String {
format!("{}: {} ({})", name, count, active)
}
let func = process.into_function();
let arg_types = func.arguments();
assert_eq!(arg_types, vec![
ValueType::String,
ValueType::Int,
ValueType::Bool
]);
Sourcepub fn result(&self) -> ValueType
pub fn result(&self) -> ValueType
Get the return type of this function.
Returns type information that can be used for:
- Compile-time type checking of expressions
- Runtime result validation
- Type inference in complex expressions
§Returns
The ValueType
that this function returns when called successfully.
For functions returning Result<T, E>
, this returns the success type T
.
§Examples
fn calculate(x: f64, y: f64) -> f64 { x * y + 1.0 }
let func = calculate.into_function();
assert_eq!(func.result(), ValueType::Double);
fn get_message() -> Result<String, Infallible> {
Ok("Hello".to_string())
}
let func = get_message.into_function();
// Returns the success type, not Result<String, Infallible>
assert_eq!(func.result(), ValueType::String);
Sourcepub fn function_type(&self) -> FunctionType
pub fn function_type(&self) -> FunctionType
Get complete function type information.
Returns a FunctionType
that combines argument and return type information.
This is useful for:
- Function signature matching
- Overload resolution
- Type checking in complex expressions
§Returns
A FunctionType
containing complete function signature information.
§Examples
fn multiply(a: i64, b: i64) -> i64 { a * b }
let func = multiply.into_function();
let func_type = func.function_type();
assert_eq!(func_type.arguments(), &[ValueType::Int, ValueType::Int]);
assert_eq!(func_type.result(), &ValueType::Int);
Sourcepub fn arguments_len(&self) -> usize
pub fn arguments_len(&self) -> usize
Get the number of arguments this function expects.
This is a convenience method equivalent to self.arguments().len()
.
Useful for quick arity checking without allocating the full argument
type vector.
§Returns
The number of parameters this function expects.
§Examples
fn no_args() -> i64 { 42 }
fn one_arg(x: i64) -> i64 { x }
fn three_args(a: i64, b: i64, c: i64) -> i64 { a + b + c }
assert_eq!(no_args.into_function().arguments_len(), 0);
assert_eq!(one_arg.into_function().arguments_len(), 1);
assert_eq!(three_args.into_function().arguments_len(), 3);
Trait Implementations§
Auto Trait Implementations§
impl<'f> Freeze for Function<'f>
impl<'f> !RefUnwindSafe for Function<'f>
impl<'f> Send for Function<'f>
impl<'f> Sync for Function<'f>
impl<'f> Unpin for Function<'f>
impl<'f> !UnwindSafe for Function<'f>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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