cel_cxx/function/
mod.rs

1//! Function registration and implementation utilities.
2//!
3//! The function system provides a flexible way to register and call functions in CEL expressions.
4//! Functions can be either compile-time declarations (type signatures only) or runtime
5//! implementations (callable code).
6//!
7//! # Key Components
8//!
9//! - [`FunctionRegistry`]: Compile-time function registry for declaring function signatures and registering implementations
10//! - [`FunctionBindings`]: Runtime function bindings for calling functions during evaluation
11//! - [`FunctionOverloads`]: Function overload management supporting multiple implementations with different signatures
12//! - **Declarations**: Use [`FunctionDecl`] trait for compile-time type checking
13//! - **Implementations**: Use [`IntoFunction`] trait for runtime function calls
14//!
15//! # Examples
16//!
17//! ```rust,no_run
18//! use cel_cxx::*;
19//!
20//! // Register a function implementation
21//! let mut env = Env::builder()
22//!     .register_global_function("greet", |name: String| -> String {
23//!         format!("Hello, {}!", name)
24//!     })?
25//!     .build()?;
26//! # Ok::<(), cel_cxx::Error>(())
27//! ```
28//!
29//! # Detailed Documentation
30//!
31//! Zero-annotation function registration for CEL expression evaluation.
32//!
33//! This module provides a type-safe, zero-annotation function registration system
34//! that allows Rust functions to be called from CEL expressions without manual
35//! type annotations or wrapper code.
36//!
37//! # Two Function Systems
38//!
39//! This module provides two distinct but complementary function systems:
40//!
41//! ## 1. Function Registration (Runtime Implementation)
42//! - **Purpose**: Register actual callable Rust functions/closures
43//! - **Entry point**: [`IntoFunction`] trait and registration methods
44//! - **Usage**: `env.register_function("name", function_impl)`
45//! - **Provides**: Executable code that can be called during expression evaluation
46//!
47//! ## 2. Function Declaration (Compile-Time Signatures)
48//! - **Purpose**: Declare function signatures for type checking without implementation
49//! - **Entry point**: [`FunctionDecl`] trait and declaration methods  
50//! - **Usage**: `env.declare_function::<SignatureType>("name")`
51//! - **Provides**: Type information for compile-time validation and overload resolution
52//!
53//! These systems work together: you can declare functions for type checking during
54//! development, then provide implementations later, or register complete functions
55//! that include both signature and implementation.
56//!
57//! # Features
58//!
59//! - **Zero-annotation registration**: Functions can be registered without explicit type annotations
60//! - **Lifetime-aware closures**: Support for closures that capture environment variables
61//! - **Reference return types**: Safe handling of functions returning borrowed data like `&str`
62//! - **Unified error handling**: Automatic conversion of `Result<T, E>` return types
63//! - **Async function support**: Optional support for async functions (requires `async` feature)
64//! - **Thread safety**: All function implementations are `Send + Sync`
65//!
66//! # How Zero-Annotation Works
67//!
68//! The zero-annotation system is built on top of Rust's type system and Generic Associated Types (GATs).
69//! When you register a function, the system automatically:
70//!
71//! 1. **Extracts argument types** from the function signature using [`FunctionDecl`]
72//! 2. **Infers return types** using the [`IntoResult`] trait
73//! 3. **Generates type-safe converters** that handle lifetime erasure safely
74//! 4. **Creates a unified interface** through the [`Function`] struct
75//!
76//! ## Type Conversion Process
77//!
78//! For each argument type `T`, the system:
79//! - Uses `T: FromValue + TypedValue` to convert from CEL values
80//! - Leverages GATs (`FromValue::Output<'a>`) to handle borrowed data like `&str`
81//! - Safely handles lifetime relationships through internal conversion mechanisms
82//!
83//! ## Safety Guarantees
84//!
85//! The lifetime handling is safe because:
86//! - Source CEL values remain valid for the entire function call
87//! - Converted arguments are immediately consumed by the target function
88//! - No references escape the function call scope
89//!
90//! # Examples
91//!
92//! ## Basic function registration
93//!
94//! ```rust,no_run
95//! use cel_cxx::{function::IntoFunction, Error};
96//!
97//! // Simple function
98//! fn add(a: i64, b: i64) -> i64 {
99//!     a + b
100//! }
101//! let func = add.into_function();
102//!
103//! // Function with error handling
104//! fn divide(a: i64, b: i64) -> Result<i64, Error> {
105//!     if b == 0 {
106//!         Err(Error::invalid_argument("division by zero"))
107//!     } else {
108//!         Ok(a / b)
109//!     }
110//! }
111//! let func = divide.into_function();
112//! ```
113//!
114//! ## Advanced: Reference return types
115//!
116//! The system handles functions that return borrowed data:
117//!
118//! ```rust,no_run
119//! use cel_cxx::function::*;
120//! // Function returning borrowed data
121//! fn get_first(items: Vec<&str>) -> &str {
122//!     items.first().map_or("", |s| *s)
123//! }
124//! let func = get_first.into_function();
125//!
126//! // The system automatically handles the lifetime relationships
127//! ```
128//!
129//! ## Closure registration
130//!
131//! ```rust,no_run
132//! use cel_cxx::function::*;
133//! // Capturing closure
134//! let multiplier = 3;
135//! let multiply = move |x: i64| -> i64 { x * multiplier };
136//! let func = multiply.into_function();
137//!
138//! // String processing closure
139//! let prefix = String::from("Hello, ");
140//! let with_prefix = move |name: &str| -> String {
141//!     format!("{}{}", prefix, name)
142//! };
143//! let func = with_prefix.into_function();
144//! ```
145//!
146//! ## Function metadata and invocation
147//!
148//! ```rust,no_run
149//! use cel_cxx::function::*;
150//! fn add(a: i64, b: i64) -> i64 { a + b }
151//! let func = add.into_function();
152//!
153//! // Get function metadata
154//! let arg_types = func.arguments(); // Vec<ValueType>
155//! let return_type = func.result();  // ValueType
156//!
157//! // Call the function (would need proper Value instances in real code)
158//! // let args = vec![Value::from(10i64), Value::from(20i64)];
159//! // let result = func.call(args);
160//! ```
161//!
162//! # Async Functions
163//!
164//! When the `async` feature is enabled, you can register async functions:
165//!
166//! ```rust,no_run
167//! # #[cfg(feature = "async")]
168//! # use cel_cxx::function::*;
169//! # async fn example() {
170//! // Async function
171//! async fn fetch_data(url: String) -> String {
172//!     // Simulate async work
173//!     tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
174//!     format!("Data from {}", url)
175//! }
176//!
177//! let func = fetch_data.into_function();
178//! // func.call() returns a Future that can be awaited
179//! # }
180//! ```
181
182use crate::error::*;
183use crate::marker::*;
184use crate::maybe_future::*;
185use crate::types::*;
186use crate::values::*;
187use std::sync::Arc;
188
189pub mod decl;
190pub use decl::*;
191
192pub mod overload;
193pub use overload::*;
194
195mod registry;
196pub use registry::*;
197
198mod bindings;
199pub use bindings::*;
200
201/// Marker trait for function argument tuples.
202///
203/// This trait is automatically implemented for tuples of types that implement
204/// [`FromValue`] and [`TypedValue`]. It serves as a constraint to ensure
205/// type safety in function registration.
206///
207/// The trait supports function signatures with 0 to 10 parameters. Each parameter
208/// type must be convertible from CEL values and have a known CEL type.
209///
210/// # Implementation Details
211///
212/// This trait is sealed and cannot be implemented outside this crate. It is
213/// automatically implemented for valid argument tuple types through procedural
214/// macros.
215///
216/// # Supported Argument Types
217///
218/// Any type that implements both [`FromValue`] and [`TypedValue`] can be used
219/// as a function argument. This includes:
220///
221/// - **Primitive types**: `bool`, `i64`, `u64`, `f64`, `String`, `Vec<u8>`
222/// - **Reference types**: `&str`, `&[u8]` (with proper lifetime handling)
223/// - **Collection types**: `Vec<T>`, `HashMap<K, V>` where `T`, `K`, `V` are valid CEL types
224/// - **Custom types**: Types that implement the required traits
225///
226/// # Note
227///
228/// This trait is sealed and cannot be implemented outside this crate.
229/// It supports function signatures with 0 to 10 parameters.
230pub trait Arguments: Sized + private::Sealed {}
231
232/// Trait for types that can be converted into function implementations.
233///
234/// This is the main entry point for function registration. Any Rust function
235/// or closure that meets the constraints can be converted into a [`Function`].
236///
237/// # Type System Integration
238///
239/// The trait uses Rust's type system to automatically:
240/// - Extract function signatures using [`FunctionDecl`]
241/// - Handle argument conversion using [`FromValue`] with GATs
242/// - Manage return type conversion using [`IntoResult`]
243/// - Support both synchronous and asynchronous functions
244///
245/// # Generic Associated Types (GATs)
246///
247/// This trait leverages GATs to handle complex lifetime relationships:
248/// - Functions returning `&str` can borrow from input parameters
249/// - Closures can capture environment variables with appropriate lifetimes
250/// - The system maintains memory safety through controlled lifetime erasure
251///
252/// # Note
253///
254/// This trait is sealed and cannot be implemented outside this crate.
255///
256/// # Type Parameters
257///
258/// - `'f`: Lifetime parameter for captured data in closures
259/// - `Fm`: Function marker (sync/async)
260/// - `Args`: Argument tuple type
261///
262/// # Examples
263///
264/// ## Simple Functions
265///
266/// ```rust
267/// # use cel_cxx::function::IntoFunction;
268/// # use std::convert::Infallible;
269/// fn add(a: i64, b: i64) -> i64 { a + b }
270/// fn divide(a: i64, b: i64) -> Result<f64, Infallible> {
271///     Ok(a as f64 / b as f64)
272/// }
273///
274/// let add_func = add.into_function();
275/// let div_func = divide.into_function();
276/// ```
277///
278/// ## Closures with Captured Variables
279///
280/// ```rust
281/// # use cel_cxx::function::IntoFunction;
282/// let factor = 2.5;
283/// let scale = move |x: f64| -> f64 { x * factor };
284/// let scale_func = scale.into_function();
285/// ```
286///
287/// ## Functions with Reference Parameters
288///
289/// ```rust
290/// # use cel_cxx::function::IntoFunction;
291/// fn process_text(text: &str, uppercase: bool) -> String {
292///     if uppercase { text.to_uppercase() } else { text.to_lowercase() }
293/// }
294/// let process_func = process_text.into_function();
295/// ```
296pub trait IntoFunction<'f, Fm: FnMarker, Args = ()>: private::Sealed<Fm, Args> {
297    /// Convert this function into a type-erased implementation.
298    ///
299    /// This method performs the conversion from a strongly-typed Rust function
300    /// to a type-erased [`Function`] that can be called from CEL expressions.
301    ///
302    /// # Returns
303    ///
304    /// A [`Function`] that encapsulates the original function with:
305    /// - Type-safe argument conversion
306    /// - Return value conversion
307    /// - Error handling
308    /// - Async support (if applicable)
309    ///
310    /// # Performance
311    ///
312    /// The conversion is zero-cost at runtime. All type checking and conversion
313    /// logic is generated at compile time.
314    fn into_function(self) -> Function<'f>;
315}
316
317/// A type-erased function implementation that can be called from CEL expressions.
318///
319/// This is the main type used to store and invoke registered functions.
320/// It provides a uniform interface for calling functions regardless of
321/// their original signature.
322///
323/// # Design
324///
325/// The `Function` struct uses dynamic dispatch through trait objects to provide
326/// a uniform interface while maintaining type safety. The original function's
327/// type information is preserved through internal trait implementations.
328///
329/// # Memory Safety
330///
331/// Despite using type erasure, the system maintains complete memory safety:
332/// - All conversions are checked at runtime
333/// - Lifetime relationships are preserved where possible
334/// - Reference parameters are handled safely through controlled lifetime management
335///
336/// # Performance
337///
338/// - Function calls involve minimal overhead (one virtual call + conversions)
339/// - Argument validation is performed once per call
340/// - Type conversions use zero-copy where possible
341///
342/// # Examples
343///
344/// ## Basic Usage
345///
346/// ```rust
347/// # use cel_cxx::function::*;
348/// fn greet(name: &str) -> String {
349///     format!("Hello, {}!", name)
350/// }
351///
352/// let func = greet.into_function();
353/// let args = vec!["World".into()];
354/// let result = func.call(args);
355/// ```
356///
357/// ## Metadata Inspection
358///
359/// ```rust
360/// # use cel_cxx::function::*;
361/// # fn greet(name: &str) -> String { format!("Hello, {}!", name) }
362/// let func = greet.into_function();
363///
364/// // Inspect function signature
365/// println!("Arguments: {:?}", func.arguments());
366/// println!("Return type: {:?}", func.result());
367/// println!("Function type: {:?}", func.function_type());
368/// ```
369#[derive(Debug, Clone)]
370pub struct Function<'f> {
371    inner: Arc<dyn ErasedFn + 'f>,
372}
373
374impl<'f> Function<'f> {
375    /// Create a new function implementation from an `ErasedFn`.
376    fn new(inner: impl ErasedFn + 'f) -> Self {
377        Self {
378            inner: Arc::new(inner),
379        }
380    }
381
382    /// Call the function with the provided arguments.
383    ///
384    /// This method invokes the function with type-safe argument conversion
385    /// and return value handling. It supports both synchronous and asynchronous
386    /// functions through the [`MaybeFuture`] return type.
387    ///
388    /// # Arguments
389    ///
390    /// * `args` - Vector of [`Value`] arguments to pass to the function
391    ///
392    /// # Returns
393    ///
394    /// Returns a [`MaybeFuture`] that represents either an immediate result or a future:
395    ///
396    /// - **Without `async` feature**: [`MaybeFuture`] is `Result<Value, Error>` - returns immediately
397    /// - **With `async` feature**: [`MaybeFuture`] can be either:
398    ///   - `MaybeFuture::Result(Result<Value, Error>)` for synchronous functions
399    ///   - `MaybeFuture::Future(BoxFuture<Result<Value, Error>>)` for async functions
400    ///
401    /// # Type Safety
402    ///
403    /// The method performs runtime type checking to ensure:
404    /// - Correct number of arguments is provided
405    /// - Each argument can be converted to the expected parameter type
406    /// - Return value conversion succeeds
407    ///
408    /// # Errors
409    ///
410    /// Returns an [`Error`] if:
411    /// - The number of arguments doesn't match the function signature
412    /// - Argument types cannot be converted to the expected types
413    /// - The function itself returns an error
414    /// - Return value conversion fails
415    ///
416    /// # Examples
417    ///
418    /// ## Synchronous function call
419    ///
420    /// ```rust
421    /// # use cel_cxx::function::*;
422    /// # use cel_cxx::values::Value;
423    /// fn add(a: i64, b: i64) -> i64 { a + b }
424    /// let func = add.into_function();
425    ///
426    /// let args = vec![Value::Int(10), Value::Int(20)];
427    /// let maybe_result = func.call(args);
428    ///
429    /// // In sync mode, extract the result directly
430    /// # #[cfg(not(feature = "async"))]
431    /// let result = maybe_result.unwrap();
432    ///
433    /// // In async mode, check if it's an immediate result
434    /// # #[cfg(feature = "async")]
435    /// let result = maybe_result.expect_result("shoud be result")?;
436    ///
437    /// assert_eq!(result, Value::Int(30));
438    /// # Ok::<(), cel_cxx::Error>(())
439    /// ```
440    ///
441    /// ## Async function call (when `async` feature is enabled)
442    ///
443    /// ```rust
444    /// # #[cfg(feature = "async")]
445    /// # async fn example() {
446    /// # use cel_cxx::function::*;
447    /// # use cel_cxx::values::Value;
448    /// async fn async_multiply(a: i64, b: i64) -> i64 { a * b }
449    /// let func = async_multiply.into_function();
450    ///
451    /// let args = vec![Value::Int(6), Value::Int(7)];
452    /// let maybe_result = func.call(args);
453    ///
454    /// // For async functions, extract and await the future
455    /// let result = maybe_result.unwrap_future().await.unwrap();
456    /// assert_eq!(result, Value::Int(42));
457    /// # }
458    /// ```
459    pub fn call<'this, 'future>(&'this self, args: Vec<Value>) -> MaybeFuture<'future, Value, Error>
460    where
461        'this: 'future,
462        Self: 'future,
463    {
464        self.inner.call(args)
465    }
466
467    /// Get the expected argument types for this function.
468    ///
469    /// Returns the function signature information that can be used for:
470    /// - Compile-time type checking
471    /// - Runtime argument validation
472    /// - Documentation generation
473    /// - IDE support and auto-completion
474    ///
475    /// # Returns
476    ///
477    /// A vector of [`ValueType`] representing the expected argument types
478    /// in the order they should be provided to [`call`](Self::call).
479    ///
480    /// # Examples
481    ///
482    /// ```rust
483    /// # use cel_cxx::function::*;
484    /// # use cel_cxx::types::ValueType;
485    /// fn process(name: &str, count: i64, active: bool) -> String {
486    ///     format!("{}: {} ({})", name, count, active)
487    /// }
488    /// let func = process.into_function();
489    ///
490    /// let arg_types = func.arguments();
491    /// assert_eq!(arg_types, vec![
492    ///     ValueType::String,
493    ///     ValueType::Int,
494    ///     ValueType::Bool
495    /// ]);
496    /// ```
497    pub fn arguments(&self) -> Vec<ValueType> {
498        self.inner.arguments()
499    }
500
501    /// Get the return type of this function.
502    ///
503    /// Returns type information that can be used for:
504    /// - Compile-time type checking of expressions
505    /// - Runtime result validation
506    /// - Type inference in complex expressions
507    ///
508    /// # Returns
509    ///
510    /// The [`ValueType`] that this function returns when called successfully.
511    /// For functions returning `Result<T, E>`, this returns the success type `T`.
512    ///
513    /// # Examples
514    ///
515    /// ```rust
516    /// # use cel_cxx::function::*;
517    /// # use cel_cxx::types::ValueType;
518    /// fn calculate(x: f64, y: f64) -> f64 { x * y + 1.0 }
519    /// let func = calculate.into_function();
520    ///
521    /// assert_eq!(func.result(), ValueType::Double);
522    /// ```
523    ///
524    /// ```rust
525    /// # use cel_cxx::function::*;
526    /// # use cel_cxx::types::ValueType;
527    /// # use std::convert::Infallible;
528    /// fn get_message() -> Result<String, Infallible> {
529    ///     Ok("Hello".to_string())
530    /// }
531    /// let func = get_message.into_function();
532    ///
533    /// // Returns the success type, not Result<String, Infallible>
534    /// assert_eq!(func.result(), ValueType::String);
535    /// ```
536    pub fn result(&self) -> ValueType {
537        self.inner.result()
538    }
539
540    /// Get complete function type information.
541    ///
542    /// Returns a [`FunctionType`] that combines argument and return type information.
543    /// This is useful for:
544    /// - Function signature matching
545    /// - Overload resolution
546    /// - Type checking in complex expressions
547    ///
548    /// # Returns
549    ///
550    /// A [`FunctionType`] containing complete function signature information.
551    ///
552    /// # Examples
553    ///
554    /// ```rust
555    /// # use cel_cxx::function::*;
556    /// # use cel_cxx::types::{ValueType, FunctionType};
557    /// fn multiply(a: i64, b: i64) -> i64 { a * b }
558    /// let func = multiply.into_function();
559    ///
560    /// let func_type = func.function_type();
561    /// assert_eq!(func_type.arguments(), &[ValueType::Int, ValueType::Int]);
562    /// assert_eq!(func_type.result(), &ValueType::Int);
563    /// ```
564    pub fn function_type(&self) -> FunctionType {
565        FunctionType::new(self.result(), self.arguments())
566    }
567
568    /// Get the number of arguments this function expects.
569    ///
570    /// This is a convenience method equivalent to `self.arguments().len()`.
571    /// Useful for quick arity checking without allocating the full argument
572    /// type vector.
573    ///
574    /// # Returns
575    ///
576    /// The number of parameters this function expects.
577    ///
578    /// # Examples
579    ///
580    /// ```rust
581    /// # use cel_cxx::function::*;
582    /// fn no_args() -> i64 { 42 }
583    /// fn one_arg(x: i64) -> i64 { x }
584    /// fn three_args(a: i64, b: i64, c: i64) -> i64 { a + b + c }
585    ///
586    /// assert_eq!(no_args.into_function().arguments_len(), 0);
587    /// assert_eq!(one_arg.into_function().arguments_len(), 1);
588    /// assert_eq!(three_args.into_function().arguments_len(), 3);
589    /// ```
590    pub fn arguments_len(&self) -> usize {
591        self.inner.arguments_len()
592    }
593}
594
595// =============================================================================
596// Implementation details
597// =============================================================================
598
599/// Internal trait for type-erased function implementations.
600///
601/// This trait provides a uniform interface for calling functions regardless
602/// of their original signature. It is not exposed publicly as users should
603/// interact with [`Function`] instead.
604trait ErasedFn: Send + Sync {
605    /// Call the function with the provided arguments.
606    fn call<'this, 'future>(&'this self, args: Vec<Value>) -> MaybeFuture<'future, Value, Error>
607    where
608        'this: 'future,
609        Self: 'future;
610
611    /// Get the expected argument types.
612    fn arguments(&self) -> Vec<ValueType>;
613
614    /// Get the return type.
615    fn result(&self) -> ValueType;
616
617    /// Get the number of expected arguments.
618    fn arguments_len(&self) -> usize;
619}
620
621macro_rules! impl_arguments {
622    ($(
623        $($ty:ident),+
624    )?) => {
625        impl<$($($ty: FromValue + TypedValue),+)?> Arguments for ($($($ty,)+)?) {}
626        impl<$($($ty: FromValue + TypedValue),+)?> private::Sealed for ($($($ty,)+)?) {}
627    }
628}
629
630impl_arguments!();
631impl_arguments!(A1);
632impl_arguments!(A1, A2);
633impl_arguments!(A1, A2, A3);
634impl_arguments!(A1, A2, A3, A4);
635impl_arguments!(A1, A2, A3, A4, A5);
636impl_arguments!(A1, A2, A3, A4, A5, A6);
637impl_arguments!(A1, A2, A3, A4, A5, A6, A7);
638impl_arguments!(A1, A2, A3, A4, A5, A6, A7, A8);
639impl_arguments!(A1, A2, A3, A4, A5, A6, A7, A8, A9);
640impl_arguments!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
641
642/// Internal trait for safely converting `FromValue::Output` to function parameter types.
643///
644/// This trait contains unsafe code for lifetime erasure and should only be used
645/// within the controlled context of function dispatch. It is not exposed publicly
646/// to ensure memory safety.
647trait Argument: FromValue + TypedValue {
648    /// Convert a CEL value to the function parameter type.
649    ///
650    /// This method safely converts a [`Value`] reference to the target type
651    /// by first using [`FromValue::from_value`] and then performing controlled
652    /// lifetime erasure via [`Self::from_output`].
653    fn make_argument(value: &Value) -> Result<Self, FromValueError> {
654        let output = <Self as FromValue>::from_value(value)?;
655        Ok(unsafe { Self::from_output(output) })
656    }
657
658    /// Convert `FromValue::Output<'a>` to `Self` by erasing lifetime information.
659    ///
660    /// # Safety
661    ///
662    /// This method performs an unsafe lifetime erasure operation that is only safe
663    /// under specific controlled conditions:
664    ///
665    /// 1. **Memory Layout Guarantee**: The method assumes that `Self` and
666    ///    `Self::Output<'a>` have identical memory layouts. This is verified by
667    ///    a debug assertion checking `size_of` equality.
668    ///
669    /// 2. **Lifetime Erasure Safety**: The lifetime parameter 'a is erased through
670    ///    unsafe pointer casting. This is safe because:
671    ///    - The input `output` is consumed (moved) into this function
672    ///    - The returned `Self` will be immediately consumed by the function call
673    ///    - No references escape the function call scope
674    ///
675    /// 3. **Controlled Usage Context**: This method is only called within the
676    ///    function dispatch mechanism where:
677    ///    - The source `&[Value]` array remains valid for the entire function call
678    ///    - The converted arguments are immediately passed to the target function
679    ///    - The function result is immediately converted via `IntoResult`
680    ///
681    /// 4. **Type System Cooperation**: For reference types like `&str`:
682    ///    - `Self::Output<'a>` is `&'a str` (borrowed from Value)
683    ///    - `Self` is `&str` (with erased lifetime)
684    ///    - The underlying string data in Value remains valid throughout the call
685    ///
686    /// The safety of this operation relies on the fact that the lifetime erasure
687    /// is temporary and scoped - the converted values never outlive the original
688    /// Value array that owns the underlying data.
689    ///
690    /// # Implementation Details
691    ///
692    /// The conversion process:
693    /// 1. Cast the reference to `output` as a pointer to `Self`
694    /// 2. Forget the original `output` to prevent double-drop
695    /// 3. Read the value from the pointer, effectively transferring ownership
696    ///
697    /// This is essentially a controlled `transmute` operation that preserves
698    /// the bit representation while changing the type signature.
699    unsafe fn from_output<'a>(output: <Self as FromValue>::Output<'a>) -> Self {
700        debug_assert!(
701            std::mem::size_of::<<Self as FromValue>::Output<'a>>() == std::mem::size_of::<Self>()
702        );
703
704        let ptr: *const Self = (&output as *const <Self as FromValue>::Output<'a>).cast();
705        std::mem::forget(output);
706        std::ptr::read(ptr)
707    }
708}
709
710// Blanket implementation for all types that implement FromValue and TypedValue
711impl<T: FromValue + TypedValue> Argument for T {}
712
713/// Internal wrapper for synchronous functions that implements [`ErasedFn`].
714///
715/// This struct wraps a function along with phantom data for its signature,
716/// allowing type-erased storage and invocation.
717struct FnWrapper<F, R, Args> {
718    func: F,
719    _phantom: std::marker::PhantomData<(R, Args)>,
720}
721
722impl<F, R, Args> FnWrapper<F, R, Args> {
723    /// Create a new function wrapper.
724    fn new(func: F) -> Self {
725        Self {
726            func,
727            _phantom: std::marker::PhantomData,
728        }
729    }
730}
731
732// =============================================================================
733// Helper macros and implementations
734// =============================================================================
735
736/// Compile-time macro to count the number of function arguments.
737macro_rules! count_args {
738    () => { 0 };
739    ($head:ident $(, $tail:ident)*) => { 1 + count_args!($($tail),*) };
740}
741use count_args;
742
743/// Macro to generate [`ErasedFn`] implementations for synchronous functions
744/// with different arities (0 to 10 parameters).
745macro_rules! impl_fn_wrapper {
746    ($($ty:ident),*) => {
747        paste::paste! {
748            impl<F, R, $($ty,)*> ErasedFn for FnWrapper<F, R, ($($ty,)*)>
749            where
750                F: Fn($($ty,)*) -> R + Send + Sync,
751                R: IntoResult + Send + Sync,
752                $($ty: FromValue + TypedValue + Send + Sync,)*
753            {
754                fn call<'this, 'future>(
755                    &'this self,
756                    args: Vec<Value>
757                ) -> MaybeFuture<'future, Value, Error>
758                where 'this: 'future, Self: 'future {
759                    let f = || {
760                        // Compile-time constant: number of expected arguments
761                        const EXPECTED_LEN: usize = count_args!($($ty),*);
762
763                        if args.len() != EXPECTED_LEN {
764                            return Err(Error::invalid_argument(
765                                format!("expected {} arguments, got {}", EXPECTED_LEN, args.len())
766                            ));
767                        }
768
769                        #[allow(unused_mut, unused_variables)]
770                        let mut iter = args.iter();
771                        $(
772                            let [< $ty:lower >] = $ty::make_argument(
773                                iter.next().expect("argument count already validated")
774                            ).map_err(|e| Error::invalid_argument(format!("argument error: {}", e)))?;
775                        )*
776
777                        let result = (self.func)($([< $ty:lower >],)*);
778                        result.into_result()
779                    };
780                    f().into()
781                }
782
783                fn arguments(&self) -> Vec<ValueType> {
784                    vec![$($ty::value_type()),*]
785                }
786
787                fn result(&self) -> ValueType {
788                    R::value_type()
789                }
790
791                fn arguments_len(&self) -> usize {
792                    count_args!($($ty),*)
793                }
794            }
795
796            // Implementation of IntoFunction for synchronous functions
797            impl<'f, F, R, $($ty,)*> IntoFunction<'f, (), ($($ty,)*)> for F
798            where
799                F: Fn($($ty,)*) -> R + Send + Sync + 'f,
800                R: IntoResult + Send + Sync + 'f,
801                ($($ty,)*): Arguments,
802                $($ty: FromValue + TypedValue + Send + Sync + 'f,)*
803            {
804                fn into_function(self) -> Function<'f> {
805                    Function::new(FnWrapper::<F, R, ($($ty,)*)>::new(self))
806                }
807            }
808
809            // Sealed implementation for synchronous functions
810            impl<'f, F, R, $($ty,)*> private::Sealed<(), ($($ty,)*)> for F
811            where
812                F: Fn($($ty,)*) -> R + Send + Sync + 'f,
813                R: IntoResult + Send + Sync + 'f,
814                ($($ty,)*): Arguments,
815                $($ty: FromValue + TypedValue + Send + Sync + 'f,)*
816            {}
817        }
818    };
819}
820
821// Generate implementations for functions with 0-10 parameters
822impl_fn_wrapper!();
823impl_fn_wrapper!(A1);
824impl_fn_wrapper!(A1, A2);
825impl_fn_wrapper!(A1, A2, A3);
826impl_fn_wrapper!(A1, A2, A3, A4);
827impl_fn_wrapper!(A1, A2, A3, A4, A5);
828impl_fn_wrapper!(A1, A2, A3, A4, A5, A6);
829impl_fn_wrapper!(A1, A2, A3, A4, A5, A6, A7);
830impl_fn_wrapper!(A1, A2, A3, A4, A5, A6, A7, A8);
831impl_fn_wrapper!(A1, A2, A3, A4, A5, A6, A7, A8, A9);
832impl_fn_wrapper!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
833
834// =============================================================================
835// Async function support (optional feature)
836// =============================================================================
837
838/// Internal wrapper for asynchronous functions that implements [`ErasedFn`].
839///
840/// This struct is similar to [`FnWrapper`] but designed for async functions
841/// that return futures. It's only available when the `async` feature is enabled.
842#[cfg(feature = "async")]
843#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
844struct FnWrapperAsync<F, R, Args> {
845    func: F,
846    _phantom: std::marker::PhantomData<(R, Args)>,
847}
848
849#[cfg(feature = "async")]
850#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
851impl<F, R, Args> FnWrapperAsync<F, R, Args> {
852    /// Create a new async function wrapper.
853    fn new(func: F) -> Self {
854        Self {
855            func,
856            _phantom: std::marker::PhantomData,
857        }
858    }
859}
860
861#[cfg(feature = "async")]
862#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
863mod async_impls {
864    use super::*;
865
866    /// Macro to generate [`ErasedFn`] implementations for asynchronous functions
867    /// with different arities (0 to 10 parameters).
868    macro_rules! impl_fn_wrapper_async {
869        ($($ty:ident),*) => {
870            paste::paste! {
871                impl<F, Fut, R, $($ty,)*> ErasedFn for FnWrapperAsync<F, R, ($($ty,)*)>
872                where
873                    F: Fn($($ty,)*) -> Fut + Send + Sync,
874                    Fut: std::future::Future<Output = R> + Send,
875                    R: IntoResult + Send + Sync,
876                    $($ty: FromValue + TypedValue + Send + Sync,)*
877                {
878                    fn call<'this, 'future>(
879                        &'this self,
880                        args: Vec<Value>
881                    ) -> MaybeFuture<'future, Value, Error>
882                    where 'this: 'future, Self: 'future {
883                        let f = || async move {
884                            // Compile-time constant: number of expected arguments
885                            const EXPECTED_LEN: usize = count_args!($($ty),*);
886
887                            if args.len() != EXPECTED_LEN {
888                                return Err(Error::invalid_argument(
889                                    format!("expected {} arguments, got {}", EXPECTED_LEN, args.len())
890                                ));
891                            }
892
893                            #[allow(unused_mut, unused_variables)]
894                            let mut iter = args.iter();
895                            $(
896                                let [< $ty:lower >] = $ty::make_argument(
897                                    iter.next().expect("argument count already validated")
898                                ).map_err(|e| Error::invalid_argument(format!("argument error: {}", e)))?;
899                            )*
900
901                            let future = (self.func)($([< $ty:lower >],)*);
902                            let result = future.await;
903                            result.into_result()
904                        };
905                        Box::pin(f()).into()
906                    }
907
908                    fn arguments(&self) -> Vec<ValueType> {
909                        vec![$($ty::value_type()),*]
910                    }
911
912                    fn result(&self) -> ValueType {
913                        R::value_type()
914                    }
915
916                    fn arguments_len(&self) -> usize {
917                        count_args!($($ty),*)
918                    }
919                }
920
921                // Implementation of IntoFunction for asynchronous functions
922                impl<'f, F, Fut, R, $($ty,)*> IntoFunction<'f, Async, ($($ty,)*)> for F
923                where
924                    F: Fn($($ty,)*) -> Fut + Send + Sync + 'f,
925                    Fut: std::future::Future<Output = R> + Send + 'f,
926                    R: IntoResult + Send + Sync + 'f,
927                    $($ty: FromValue + TypedValue + Send + Sync + 'f,)*
928                {
929                    fn into_function(self) -> Function<'f> {
930                        Function::new(FnWrapperAsync::<F, R, ($($ty,)*)>::new(self))
931                    }
932                }
933
934                // Sealed implementation for asynchronous functions
935                impl<'f, F, Fut, R, $($ty,)*> private::Sealed<Async, ($($ty,)*)> for F
936                where
937                    F: Fn($($ty,)*) -> Fut + Send + Sync + 'f,
938                    Fut: std::future::Future<Output = R> + Send + 'f,
939                    R: IntoResult + Send + Sync + 'f,
940                    $($ty: FromValue + TypedValue + Send + Sync + 'f,)*
941                {}
942            }
943        };
944    }
945
946    impl_fn_wrapper_async!();
947    impl_fn_wrapper_async!(A1);
948    impl_fn_wrapper_async!(A1, A2);
949    impl_fn_wrapper_async!(A1, A2, A3);
950    impl_fn_wrapper_async!(A1, A2, A3, A4);
951    impl_fn_wrapper_async!(A1, A2, A3, A4, A5);
952    impl_fn_wrapper_async!(A1, A2, A3, A4, A5, A6);
953    impl_fn_wrapper_async!(A1, A2, A3, A4, A5, A6, A7);
954    impl_fn_wrapper_async!(A1, A2, A3, A4, A5, A6, A7, A8);
955    impl_fn_wrapper_async!(A1, A2, A3, A4, A5, A6, A7, A8, A9);
956    impl_fn_wrapper_async!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
957}
958
959// =============================================================================
960// Additional implementations
961// =============================================================================
962
963/// Debug implementation for type-erased functions.
964impl std::fmt::Debug for dyn ErasedFn + '_ {
965    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
966        f.write_str("<function>")
967    }
968}
969
970/// Private module for sealed traits to prevent external implementations.
971mod private {
972    #[derive(Debug)]
973    pub enum Placeholder {}
974
975    pub trait Sealed<T = Placeholder, U = Placeholder> {}
976}
977
978#[cfg(test)]
979mod tests {
980    use super::*;
981
982    #[test]
983    fn test_basic_function_registration() {
984        // Test basic function registration and metadata extraction
985        fn add(a: i64, b: i64) -> i64 {
986            a + b
987        }
988        let func = add.into_function();
989
990        assert_eq!(func.arguments(), vec![ValueType::Int, ValueType::Int]);
991        assert_eq!(func.result(), ValueType::Int);
992
993        // Test closure registration
994        let multiplier = 3;
995        let multiply = move |x: i64| -> i64 { x * multiplier };
996        let func2 = multiply.into_function();
997
998        assert_eq!(func2.arguments(), vec![ValueType::Int]);
999        assert_eq!(func2.result(), ValueType::Int);
1000    }
1001
1002    #[test]
1003    fn test_reference_return_functions() {
1004        // Test functions that return borrowed data
1005        fn return_arg(a: &str) -> &str {
1006            a
1007        }
1008        let func = return_arg.into_function();
1009
1010        assert_eq!(func.arguments(), vec![ValueType::String]);
1011        assert_eq!(func.result(), ValueType::String);
1012
1013        // Test function invocation
1014        let result = func.call(vec!["hello".into()]);
1015        let result = result.expect_result("test_reference_return_functions");
1016        assert_eq!(result.unwrap(), "hello".into());
1017    }
1018
1019    #[test]
1020    fn test_closure_with_captured_data() {
1021        // Test closures that capture environment variables
1022        let prefix = String::from("Hello, ");
1023        let with_prefix = move |name: &str| -> String { format!("{}{}", prefix, name) };
1024
1025        let func = with_prefix.into_function();
1026
1027        assert_eq!(func.arguments(), vec![ValueType::String]);
1028        assert_eq!(func.result(), ValueType::String);
1029
1030        // Test function invocation
1031        let result = func.call(vec!["world".into()]);
1032        let result = result.expect_result("test_closure_with_captured_data");
1033        assert_eq!(result.unwrap(), "Hello, world".into());
1034    }
1035
1036    #[test]
1037    fn test_zero_parameter_function() {
1038        // Test functions with no parameters
1039        fn get_answer() -> i64 {
1040            42
1041        }
1042        let func = get_answer.into_function();
1043
1044        assert_eq!(func.arguments(), vec![]);
1045        assert_eq!(func.result(), ValueType::Int);
1046
1047        // Test function invocation
1048        let result = func.call(vec![]);
1049        let result = result.expect_result("test_zero_parameter_function");
1050        assert_eq!(result.unwrap(), 42i64.into());
1051    }
1052
1053    #[test]
1054    fn test_multiple_parameter_function() {
1055        // Test functions with multiple parameters
1056        fn add_three(a: i64, b: i64, c: i64) -> i64 {
1057            a + b + c
1058        }
1059        let func = add_three.into_function();
1060
1061        assert_eq!(
1062            func.arguments(),
1063            vec![ValueType::Int, ValueType::Int, ValueType::Int]
1064        );
1065        assert_eq!(func.result(), ValueType::Int);
1066
1067        // Test function invocation
1068        let result = func.call(vec![1i64.into(), 2i64.into(), 3i64.into()]);
1069        let result = result.expect_result("test_multiple_parameter_function");
1070        assert_eq!(result.unwrap(), 6i64.into());
1071    }
1072
1073    #[test]
1074    fn test_result_error_handling() {
1075        // Test functions that return Result for error handling
1076        fn divide(a: i64, b: i64) -> Result<i64, std::io::Error> {
1077            if b == 0 {
1078                Err(std::io::Error::new(
1079                    std::io::ErrorKind::InvalidInput,
1080                    "division by zero",
1081                ))
1082            } else {
1083                Ok(a / b)
1084            }
1085        }
1086
1087        let func = divide.into_function();
1088
1089        assert_eq!(func.arguments(), vec![ValueType::Int, ValueType::Int]);
1090        assert_eq!(func.result(), ValueType::Int);
1091
1092        // Test successful case
1093        let result = func.call(vec![10i64.into(), 2i64.into()]);
1094        let result = result.expect_result("test_result_error_handling_success");
1095        assert_eq!(result.unwrap(), 5i64.into());
1096
1097        // Test error case
1098        let result = func.call(vec![10i64.into(), 0i64.into()]);
1099        let result = result.expect_result("test_result_error_handling_error");
1100        assert!(result.is_err());
1101    }
1102}