cel_cxx/macros/expander.rs
1use super::{MacroExprFactory, Expr};
2
3/// Trait for global macro expansion functions.
4///
5/// A global macro expander receives a list of arguments and produces a transformed
6/// expression. Global macros are triggered by function calls, not method calls.
7///
8/// # Type Requirements
9///
10/// The expander function must be:
11/// - `Fn(&mut MacroExprFactory, Vec<Expr>) -> Option<Expr>`: The expansion signature
12/// - `Send + Sync`: Thread-safe for use in concurrent environments
13/// - `'static`: No borrowed references in the closure
14///
15/// # Return Value
16///
17/// - `Some(expr)`: The macro expansion succeeded and `expr` replaces the original call
18/// - `None`: The macro cannot be expanded (keeps the original expression)
19///
20/// # Examples
21///
22/// ```rust,no_run
23/// # use cel_cxx::macros::{GlobalMacroExpander, MacroExprFactory, Expr};
24/// // Simple constant-folding macro
25/// fn optimize_add(factory: &mut MacroExprFactory, args: Vec<Expr>) -> Option<Expr> {
26/// if args.len() != 2 {
27/// return None;
28/// }
29///
30/// // If both args are constant integers, fold them
31/// let left = args[0].kind()?.as_constant()?.as_int()?;
32/// let right = args[1].kind()?.as_constant()?.as_int()?;
33///
34/// Some(factory.new_const(left + right))
35/// }
36/// ```
37pub trait GlobalMacroExpander
38 : Fn(&MacroExprFactory<'_>, Vec<Expr>) -> Option<Expr> + Send + Sync
39{}
40
41impl<'f, F> GlobalMacroExpander for F where F
42 : Fn(&MacroExprFactory<'_>, Vec<Expr>) -> Option<Expr> + Send + Sync
43 + 'f
44{}
45
46/// Trait for receiver macro expansion functions.
47///
48/// A receiver macro expander receives a target expression and a list of arguments,
49/// then produces a transformed expression. Receiver macros are triggered by method
50/// calls on a target object.
51///
52/// # Type Requirements
53///
54/// The expander function must be:
55/// - `Fn(&mut MacroExprFactory, Expr, Vec<Expr>) -> Option<Expr>`: The expansion signature
56/// - `Send + Sync`: Thread-safe for use in concurrent environments
57/// - `'static`: No borrowed references in the closure
58///
59/// # Parameters
60///
61/// - `factory`: Factory for creating new expression nodes
62/// - `target`: The receiver expression (the object before the dot)
63/// - `args`: The argument list passed to the method
64///
65/// # Return Value
66///
67/// - `Some(expr)`: The macro expansion succeeded and `expr` replaces the original call
68/// - `None`: The macro cannot be expanded (keeps the original expression)
69///
70/// # Examples
71///
72/// ```rust,no_run
73/// # use cel_cxx::macros::{ReceiverMacroExpander, MacroExprFactory, Expr};
74/// // Macro for optional chaining: target.get_or(default)
75/// fn get_or_macro(
76/// factory: &mut MacroExprFactory,
77/// target: Expr,
78/// mut args: Vec<Expr>
79/// ) -> Option<Expr> {
80/// if args.len() != 1 {
81/// return None;
82/// }
83///
84/// let default_value = args.pop()?;
85///
86/// // Expand to: target != null ? target : default_value
87/// Some(factory.new_call("_?_:_", &[
88/// factory.new_call("_!=_", &[target.clone(), factory.new_const(())]),
89/// target,
90/// default_value,
91/// ]))
92/// }
93/// ```
94pub trait ReceiverMacroExpander
95 : Fn(&MacroExprFactory<'_>, Expr, Vec<Expr>) -> Option<Expr> + Send + Sync
96{}
97
98impl<'f, F> ReceiverMacroExpander for F where F
99 : Fn(&MacroExprFactory<'_>, Expr, Vec<Expr>) -> Option<Expr> + Send + Sync
100 + 'f
101{}