cel_cxx/env/
mod.rs

1use crate::function::{Arguments, FunctionDecl, FunctionDeclWithNonEmptyArguments, FunctionRegistry, IntoFunction, NonEmptyArguments};
2use crate::variable::VariableRegistry;
3use crate::{FnMarker, FnMarkerAggr, IntoConstant, Macro, RuntimeMarker};
4use std::collections::HashSet;
5use std::sync::Arc;
6
7mod inner;
8
9use crate::{Error, Program, TypedValue};
10pub(crate) use inner::{EnvInner, EnvInnerOptions};
11
12#[cfg(feature = "async")]
13#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
14use crate::marker::Async;
15
16/// CEL expression evaluation environment.
17///
18/// The `Env` struct represents a CEL environment that can compile expressions
19/// into programs. It encapsulates function registries, variable declarations,
20/// and type information needed for expression compilation.
21///
22/// # Type Parameters
23///
24/// - `'f`: Lifetime of functions registered in this environment
25/// - `Fm`: Function marker type indicating sync/async function support
26/// - `Rm`: Runtime marker type indicating the async runtime (if any)
27///
28/// # Examples
29///
30/// ## Basic Usage
31///
32/// ```rust,no_run
33/// use cel_cxx::*;
34///
35/// let env = Env::builder()
36///     .declare_variable::<String>("name")?
37///     .build()?;
38///     
39/// let program = env.compile("'Hello, ' + name")?;
40/// # Ok::<(), cel_cxx::Error>(())
41/// ```
42///
43/// ## With Custom Functions
44///
45/// ```rust,no_run
46/// use cel_cxx::*;
47///
48/// let env = Env::builder()
49///     .register_global_function("add", |x: i64, y: i64| -> i64 { x + y })?
50///     .build()?;
51///     
52/// let program = env.compile("add(10, 20)")?;
53/// # Ok::<(), cel_cxx::Error>(())
54/// ```
55pub struct Env<'f, Fm: FnMarker = (), Rm: RuntimeMarker = ()> {
56    pub(crate) inner: Arc<EnvInner<'f>>,
57    _fn_marker: std::marker::PhantomData<Fm>,
58    _rt_marker: std::marker::PhantomData<Rm>,
59}
60
61/// Type alias for asynchronous CEL environments.
62///
63/// This is a convenience type alias for environments that support asynchronous
64/// function evaluation.
65#[cfg(feature = "async")]
66#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
67pub type AsyncEnv<'f, Rm = ()> = Env<'f, Async, Rm>;
68
69impl<'f> Env<'f> {
70    /// Creates a new environment builder.
71    ///
72    /// This is the starting point for creating a CEL environment. The builder
73    /// allows you to register functions, declare variables, and configure
74    /// the environment before building it.
75    ///
76    /// # Examples
77    ///
78    /// ```rust,no_run
79    /// use cel_cxx::*;
80    ///
81    /// let builder = Env::builder();
82    /// ```
83    pub fn builder() -> EnvBuilder<'f, ()> {
84        EnvBuilder::<(), ()>::new()
85    }
86}
87
88impl<'f, Fm: FnMarker, Rm: RuntimeMarker> Env<'f, Fm, Rm> {
89    /// Compiles a CEL expression into a Program.
90    ///
91    /// This method takes a CEL expression as a string or byte slice and compiles
92    /// it into a [`Program`] that can be evaluated with different activations.
93    ///
94    /// # Arguments
95    ///
96    /// * `source` - The CEL expression to compile
97    ///
98    /// # Returns
99    ///
100    /// Returns a [`Result`] containing the compiled [`Program`] or an [`Error`]
101    /// if compilation fails.
102    ///
103    /// # Examples
104    ///
105    /// ```rust,no_run
106    /// use cel_cxx::*;
107    ///
108    /// let env = Env::builder().build().unwrap();
109    /// let program = env.compile("1 + 2 * 3").unwrap();
110    /// ```
111    ///
112    /// # Errors
113    ///
114    /// Returns an error if:
115    /// - The expression contains syntax errors
116    /// - Referenced functions or variables are not declared
117    /// - Type checking fails
118    pub fn compile<S: AsRef<[u8]>>(&self, source: S) -> Result<Program<'f, Fm, Rm>, Error> {
119        self.inner.clone().compile::<Fm, Rm, _>(source)
120    }
121}
122
123/// Builder for creating CEL environments.
124///
125/// The `EnvBuilder` allows you to configure a CEL environment by registering
126/// functions, declaring variables, and setting up runtime options before
127/// building the final environment.
128///
129/// # Type Parameters
130///
131/// - `'f`: Lifetime of functions that will be registered
132/// - `Fm`: Function marker type indicating sync/async function support
133/// - `Rm`: Runtime marker type indicating the async runtime (if any)
134///
135/// # Examples
136///
137/// ```rust,no_run
138/// use cel_cxx::*;
139///
140/// let env = Env::builder()
141///     .register_global_function("double", |x: i64| -> i64 { x * 2 })?
142///     .declare_variable::<String>("message")?
143///     .build()?;
144/// # Ok::<(), cel_cxx::Error>(())
145/// ```
146pub struct EnvBuilder<'f, Fm: FnMarker = (), Rm: RuntimeMarker = ()> {
147    macros: HashSet<Macro>,
148    function_registry: FunctionRegistry<'f>,
149    variable_registry: VariableRegistry,
150    options: EnvInnerOptions,
151    _fn_marker: std::marker::PhantomData<Fm>,
152    _rt_marker: std::marker::PhantomData<Rm>,
153}
154
155impl<'f, Fm: FnMarker, Rm: RuntimeMarker> EnvBuilder<'f, Fm, Rm> {
156    /// Creates a new environment builder.
157    ///
158    /// # Examples
159    ///
160    /// ```rust,no_run
161    /// use cel_cxx::*;
162    ///
163    /// let builder = EnvBuilder::<()>::new();
164    /// ```
165    pub fn new() -> Self {
166        EnvBuilder {
167            macros: HashSet::new(),
168            function_registry: FunctionRegistry::new(),
169            variable_registry: VariableRegistry::new(),
170            options: EnvInnerOptions::default(),
171            _fn_marker: std::marker::PhantomData,
172            _rt_marker: std::marker::PhantomData,
173        }
174    }
175}
176
177impl<'f, Fm: FnMarker, Rm: RuntimeMarker> EnvBuilder<'f, Fm, Rm> {
178    /// Sets the CEL container for the environment, which acts as a namespace for unqualified names.
179    ///
180    /// **Default**: Empty string (root scope)
181    ///
182    /// The container influences how unqualified names (like function or variable names) are
183    /// resolved during expression compilation. This affects the CEL runtime's name resolution
184    /// behavior for types, functions, and variables.
185    ///
186    /// # CEL Syntax Impact
187    ///
188    /// When a container is set, unqualified names in CEL expressions are automatically prefixed
189    /// with the container namespace:
190    ///
191    /// ```cel
192    /// // With container "my.app", this expression:
193    /// MyMessage{field: 123}
194    /// // is equivalent to:
195    /// my.app.MyMessage{field: 123}
196    /// ```
197    ///
198    /// # Examples
199    ///
200    /// ```rust,no_run
201    /// use cel_cxx::*;
202    /// 
203    /// // Set container for protobuf message resolution
204    /// let env = Env::builder()
205    ///     .with_container("com.example.proto")
206    ///     .build()?;
207    /// 
208    /// // Now "UserMessage" resolves to "com.example.proto.UserMessage"
209    /// let program = env.compile("UserMessage{name: 'Alice', id: 123}")?;
210    /// # Ok::<(), cel_cxx::Error>(())
211    /// ```
212    pub fn with_container(mut self, container: impl Into<String>) -> Self {
213        self.options.container = container.into();
214        self
215    }
216
217    /// Enables or disables the CEL standard library of functions and macros.
218    ///
219    /// **Default**: Enabled (`true`)
220    ///
221    /// The standard library provides a rich set of common functions for types like `string`,
222    /// `list`, `map`, as well as logical and arithmetic operators. Disabling it can reduce 
223    /// the environment's footprint if only custom functions are needed.
224    ///
225    /// # CEL Syntax Impact
226    ///
227    /// When enabled, provides access to all standard CEL operations:
228    /// - **Arithmetic**: `+`, `-`, `*`, `/`, `%`
229    /// - **Comparison**: `==`, `!=`, `<`, `<=`, `>`, `>=`
230    /// - **Logical**: `&&`, `||`, `!`
231    /// - **String operations**: `+` (concatenation), `contains()`, `startsWith()`, `endsWith()`, `size()`
232    /// - **List operations**: `size()`, `in`, `[]` (indexing), `+` (concatenation)
233    /// - **Map operations**: `size()`, `in`, `[]` (key access), `+` (merge)
234    /// - **Type conversions**: `int()`, `uint()`, `double()`, `string()`, `bytes()`
235    /// - **Conditional**: `? :` (ternary operator)
236    /// - **Macros**: `has()`, `all()`, `exists()`, `exists_one()`, `map()`, `filter()`
237    ///
238    /// # Examples
239    ///
240    /// ```rust
241    /// use cel_cxx::*;
242    /// 
243    /// // Standard library enabled (default)
244    /// let env = Env::builder()
245    ///     .with_standard(true)
246    ///     .build()?;
247    /// 
248    /// // Can use standard functions
249    /// let program = env.compile("'hello'.size() + ' world'.size() == 11")?;
250    /// let result = program.evaluate(&Activation::new())?;
251    /// assert_eq!(result, Value::Bool(true));
252    /// 
253    /// // Standard library disabled
254    /// let env_minimal = Env::builder()
255    ///     .with_standard(false)
256    ///     .build()?;
257    /// 
258    /// // Standard functions not available - would cause compilation error
259    /// // env_minimal.compile("'hello'.size()")?; // Error!
260    /// # Ok::<(), cel_cxx::Error>(())
261    /// ```
262    pub fn with_standard(mut self, enable: bool) -> Self {
263        self.options.enable_standard = enable;
264        self
265    }
266
267    /// Enables or disables support for CEL's optional types and related syntax.
268    ///
269    /// **Default**: Disabled (`false`)
270    ///
271    /// This enables the `optional` type and related features like optional field selection (`.?`),
272    /// optional index/key access (`[?_]`), and optional value construction (`{?key: ...}`).
273    /// Required for some extensions like regex that return optional values.
274    ///
275    /// # CEL Syntax Impact
276    ///
277    /// When enabled, adds support for:
278    /// - **Optional type**: `optional<T>` for values that may or may not be present
279    /// - **Optional field selection**: `msg.?field` returns `optional<T>` instead of error
280    /// - **Optional indexing**: `list[?index]` and `map[?key]` return `optional<T>`
281    /// - **Optional map construction**: `{?'key': value}` only includes entry if value is present
282    /// - **Optional methods**: `.hasValue()`, `.value()`, `.orValue(default)`
283    /// - **Optional literals**: `optional.of(value)`, `optional.none()`
284    ///
285    /// # Examples
286    ///
287    /// ```rust
288    /// use cel_cxx::*;
289    /// 
290    /// let env = Env::builder()
291    ///     .with_optional(true)
292    ///     .build()?;
293    /// 
294    /// // Optional field selection
295    /// let program = env.compile("msg.?field.orValue('default')")?;
296    /// 
297    /// // Optional map construction
298    /// let program2 = env.compile("{'name': 'bob', ?'age': optional.of(25)}")?;
299    /// 
300    /// // Optional indexing
301    /// let program3 = env.compile("list[?5].hasValue()")?;
302    /// # Ok::<(), cel_cxx::Error>(())
303    /// ```
304    pub fn with_optional(mut self, enable: bool) -> Self {
305        self.options.enable_optional = enable;
306        self
307    }
308
309    /// Enables or disables the Bindings extension.
310    ///
311    /// **Default**: Disabled (`false`)
312    ///
313    /// This extension provides the `cel.bind()` macro, which allows for temporary variable
314    /// bindings within a CEL expression to improve readability and performance by avoiding
315    /// repeated calculations.
316    ///
317    /// # Available Functions
318    ///
319    /// | Function | Description | Example |
320    /// |----------|-------------|---------|
321    /// | `cel.bind(var, init, result)` | Bind variable to initialization expression | `cel.bind(x, 5, x * x)` |
322    ///
323    /// # CEL Syntax Impact
324    ///
325    /// When enabled, adds the `cel.bind()` macro that creates local variable scopes:
326    /// - Variables are scoped to the result expression
327    /// - Supports nested bindings
328    /// - Enables performance optimization through value reuse
329    /// - Improves readability of complex expressions
330    ///
331    /// # Examples
332    ///
333    /// ```rust
334    /// use cel_cxx::*;
335    /// 
336    /// let env = Env::builder()
337    ///     .with_ext_bindings(true)
338    ///     .build()?;
339    /// 
340    /// // Simple binding
341    /// let program = env.compile("cel.bind(x, 5, x * x)")?;
342    /// let result = program.evaluate(&Activation::new())?;
343    /// assert_eq!(result, Value::Int(25));
344    /// 
345    /// // Nested bindings for complex calculations
346    /// let program2 = env.compile(r#"
347    ///     cel.bind(a, 'hello',
348    ///       cel.bind(b, 'world', 
349    ///         a + ' ' + b + '!'))
350    /// "#)?;
351    /// # Ok::<(), cel_cxx::Error>(())
352    /// ```
353    pub fn with_ext_bindings(mut self, enable: bool) -> Self {
354        self.options.enable_ext_bindings = enable;
355        self
356    }
357
358    /// Enables or disables the Comprehensions extension.
359    ///
360    /// **Default**: Disabled (`false`)
361    ///
362    /// This extension provides support for two-variable comprehensions, which are a way to iterate
363    /// over a collection and perform an operation on each element.
364    ///
365    /// The two-variable form of comprehensions looks similar to the one-variable counterparts.
366    /// Where possible, the same macro names were used and additional macro signatures added.
367    /// The notable distinction for two-variable comprehensions is the introduction of
368    /// `transformList`, `transformMap`, and `transformMapEntry` support for list and map types
369    /// rather than the more traditional `map` and `filter` macros.
370    ///
371    /// # All
372    ///
373    /// Comprehension which tests whether all elements in the list or map satisfy a given
374    /// predicate. The `all` macro evaluates in a manner consistent with logical AND and will
375    /// short-circuit when encountering a `false` value.
376    ///
377    /// ```cel
378    /// <list>.all(indexVar, valueVar, <predicate>) -> bool
379    /// <map>.all(keyVar, valueVar, <predicate>) -> bool
380    /// ```
381    ///
382    /// Examples:
383    ///
384    /// ```cel
385    /// [1, 2, 3].all(i, j, i < j) // returns true
386    /// {'hello': 'world', 'taco': 'taco'}.all(k, v, k != v) // returns false
387    ///
388    /// // Combines two-variable comprehension with single variable
389    /// {'h': ['hello', 'hi'], 'j': ['joke', 'jog']}
390    ///     .all(k, vals, vals.all(v, v.startsWith(k))) // returns true
391    /// ```
392    ///
393    /// # Exists
394    ///
395    /// Comprehension which tests whether any element in a list or map exists which satisfies
396    /// a given predicate. The `exists` macro evaluates in a manner consistent with logical OR
397    /// and will short-circuit when encountering a `true` value.
398    ///
399    /// ```cel
400    /// <list>.exists(indexVar, valueVar, <predicate>) -> bool
401    /// <map>.exists(keyVar, valueVar, <predicate>) -> bool
402    /// ```
403    ///
404    /// Examples:
405    ///
406    /// ```cel
407    /// {'greeting': 'hello', 'farewell': 'goodbye'}
408    ///     .exists(k, v, k.startsWith('good') || v.endsWith('bye')) // returns true
409    /// [1, 2, 4, 8, 16].exists(i, v, v == 1024 && i == 10) // returns false
410    /// ```
411    ///
412    /// # ExistsOne
413    ///
414    /// Comprehension which tests whether exactly one element in a list or map exists which
415    /// satisfies a given predicate expression. This comprehension does not short-circuit in
416    /// keeping with the one-variable exists one macro semantics.
417    ///
418    /// ```cel
419    /// <list>.existsOne(indexVar, valueVar, <predicate>)
420    /// <map>.existsOne(keyVar, valueVar, <predicate>)
421    /// ```
422    ///
423    /// This macro may also be used with the `exists_one` function name, for compatibility
424    /// with the one-variable macro of the same name.
425    ///
426    /// Examples:
427    ///
428    /// ```cel
429    /// [1, 2, 1, 3, 1, 4].existsOne(i, v, i == 1 || v == 1) // returns false
430    /// [1, 1, 2, 2, 3, 3].existsOne(i, v, i == 2 && v == 2) // returns true
431    /// {'i': 0, 'j': 1, 'k': 2}.existsOne(i, v, i == 'l' || v == 1) // returns true
432    /// ```
433    ///
434    /// # TransformList
435    ///
436    /// Comprehension which converts a map or a list into a list value. The output expression
437    /// of the comprehension determines the contents of the output list. Elements in the list
438    /// may optionally be filtered according to a predicate expression, where elements that
439    /// satisfy the predicate are transformed.
440    ///
441    /// ```cel
442    /// <list>.transformList(indexVar, valueVar, <transform>)
443    /// <list>.transformList(indexVar, valueVar, <filter>, <transform>)
444    /// <map>.transformList(keyVar, valueVar, <transform>)
445    /// <map>.transformList(keyVar, valueVar, <filter>, <transform>)
446    /// ```
447    ///
448    /// Examples:
449    ///
450    /// ```cel
451    /// [1, 2, 3].transformList(indexVar, valueVar,
452    ///   (indexVar * valueVar) + valueVar) // returns [1, 4, 9]
453    /// [1, 2, 3].transformList(indexVar, valueVar, indexVar % 2 == 0,
454    ///   (indexVar * valueVar) + valueVar) // returns [1, 9]
455    /// {'greeting': 'hello', 'farewell': 'goodbye'}
456    ///   .transformList(k, _, k) // returns ['greeting', 'farewell']
457    /// {'greeting': 'hello', 'farewell': 'goodbye'}
458    ///   .transformList(_, v, v) // returns ['hello', 'goodbye']
459    /// ```
460    ///
461    /// # TransformMap
462    ///
463    /// Comprehension which converts a map or a list into a map value. The output expression
464    /// of the comprehension determines the value of the output map entry; however, the key
465    /// remains fixed. Elements in the map may optionally be filtered according to a predicate
466    /// expression, where elements that satisfy the predicate are transformed.
467    ///
468    /// ```cel
469    /// <list>.transformMap(indexVar, valueVar, <transform>)
470    /// <list>.transformMap(indexVar, valueVar, <filter>, <transform>)
471    /// <map>.transformMap(keyVar, valueVar, <transform>)
472    /// <map>.transformMap(keyVar, valueVar, <filter>, <transform>)
473    /// ```
474    ///
475    /// Examples:
476    ///
477    /// ```cel
478    /// [1, 2, 3].transformMap(indexVar, valueVar,
479    ///   (indexVar * valueVar) + valueVar) // returns {0: 1, 1: 4, 2: 9}
480    /// [1, 2, 3].transformMap(indexVar, valueVar, indexVar % 2 == 0,
481    ///   (indexVar * valueVar) + valueVar) // returns {0: 1, 2: 9}
482    /// {'greeting': 'hello'}.transformMap(k, v, v + '!') // returns {'greeting': 'hello!'}
483    /// ```
484    ///
485    /// # TransformMapEntry
486    ///
487    /// Comprehension which converts a map or a list into a map value; however, this transform
488    /// expects the entry expression be a map literal. If the tranform produces an entry which
489    /// duplicates a key in the target map, the comprehension will error.  Note, that key
490    /// equality is determined using CEL equality which asserts that numeric values which are
491    /// equal, even if they don't have the same type will cause a key collision.
492    ///
493    /// Elements in the map may optionally be filtered according to a predicate expression, where
494    /// elements that satisfy the predicate are transformed.
495    ///
496    /// ```cel
497    /// <list>.transformMapEntry(indexVar, valueVar, <transform>)
498    /// <list>.transformMapEntry(indexVar, valueVar, <filter>, <transform>)
499    /// <map>.transformMapEntry(keyVar, valueVar, <transform>)
500    /// <map>.transformMapEntry(keyVar, valueVar, <filter>, <transform>)
501    /// ```
502    ///
503    /// Examples:
504    ///
505    /// ```cel
506    /// // returns {'hello': 'greeting'}
507    /// {'greeting': 'hello'}.transformMapEntry(keyVar, valueVar, {valueVar: keyVar})
508    /// // reverse lookup, require all values in list be unique
509    /// [1, 2, 3].transformMapEntry(indexVar, valueVar, {valueVar: indexVar})
510    ///
511    /// {'greeting': 'aloha', 'farewell': 'aloha'}
512    ///   .transformMapEntry(keyVar, valueVar, {valueVar: keyVar}) // error, duplicate key
513    /// ```
514    pub fn with_ext_comprehensions(mut self, enable: bool) -> Self {
515        self.options.enable_ext_comprehensions = enable;
516        self
517    }
518
519    /// Enables or disables the Encoders extension.
520    ///
521    /// **Default**: Disabled (`false`)
522    ///
523    /// This extension provides functions for encoding and decoding between common data formats,
524    /// such as Base64. All functions handle edge cases gracefully and maintain CEL's safety guarantees.
525    ///
526    /// # Available Functions
527    ///
528    /// | Function | Description | Example |
529    /// |----------|-------------|---------|
530    /// | `base64.encode(bytes)` | Encode bytes to Base64 string | `base64.encode(b'hello')` |
531    /// | `base64.decode(string)` | Decode Base64 string to bytes | `base64.decode('aGVsbG8=')` |
532    ///
533    /// # CEL Syntax Impact
534    ///
535    /// When enabled, adds encoding/decoding functions in the `base64` namespace:
536    /// - Supports both standard and raw (unpadded) Base64 encoding
537    /// - Automatically handles missing padding in decode operations
538    /// - Returns errors for invalid Base64 input
539    ///
540    /// # Examples
541    ///
542    /// ```rust
543    /// use cel_cxx::*;
544    /// 
545    /// let env = Env::builder()
546    ///     .with_ext_encoders(true)
547    ///     .build()?;
548    /// 
549    /// // Encode bytes to Base64
550    /// let program = env.compile("base64.encode(b'hello')")?;
551    /// let result = program.evaluate(&Activation::new())?;
552    /// assert_eq!(result, Value::String("aGVsbG8=".into()));
553    /// 
554    /// // Decode Base64 to bytes
555    /// let program2 = env.compile("base64.decode('aGVsbG8=')")?;
556    /// let result2 = program2.evaluate(&Activation::new())?;
557    /// assert_eq!(result2, Value::Bytes(b"hello".to_vec()));
558    /// # Ok::<(), cel_cxx::Error>(())
559    /// ```
560    pub fn with_ext_encoders(mut self, enable: bool) -> Self {
561        self.options.enable_ext_encoders = enable;
562        self
563    }
564
565    /// Enables or disables the Lists extension.
566    ///
567    /// **Default**: Disabled (`false`)
568    ///
569    /// This extension provides additional functions for working with lists, such as slicing,
570    /// flattening, sorting, and deduplication. All functions maintain CEL's immutability 
571    /// guarantees and return new lists rather than modifying existing ones.
572    ///
573    /// # Available Functions
574    ///
575    /// | Function | Description | Example |
576    /// |----------|-------------|---------|
577    /// | `list.slice(start, end)` | Extract sub-list | `[1,2,3,4].slice(1,3)` → `[2,3]` |
578    /// | `list.flatten()` | Flatten nested lists | `[[1,2],[3,4]].flatten()` → `[1,2,3,4]` |
579    /// | `list.flatten(depth)` | Flatten to specified depth | `[1,[2,[3]]].flatten(1)` → `[1,2,[3]]` |
580    /// | `list.distinct()` | Remove duplicates | `[1,2,2,3].distinct()` → `[1,2,3]` |
581    /// | `list.reverse()` | Reverse list order | `[1,2,3].reverse()` → `[3,2,1]` |
582    /// | `list.sort()` | Sort comparable elements | `[3,1,2].sort()` → `[1,2,3]` |
583    /// | `list.sortBy(var, expr)` | Sort by key expression | `users.sortBy(u, u.age)` |
584    /// | `lists.range(n)` | Generate number sequence | `lists.range(3)` → `[0,1,2]` |
585    /// | `lists.range(start, end)` | Generate range | `lists.range(2,5)` → `[2,3,4]` |
586    ///
587    /// # CEL Syntax Impact
588    ///
589    /// When enabled, adds advanced list manipulation capabilities:
590    /// - Zero-based indexing for all operations
591    /// - Type safety for sort operations (comparable types only)
592    /// - Efficient deduplication and flattening algorithms
593    /// - Lazy evaluation for range generation
594    ///
595    /// # Examples
596    ///
597    /// ```rust
598    /// use cel_cxx::*;
599    /// 
600    /// let env = Env::builder()
601    ///     .with_ext_lists(true)
602    ///     .build()?;
603    /// 
604    /// // List slicing
605    /// let program = env.compile("[1, 2, 3, 4].slice(1, 3)")?;
606    /// let result = program.evaluate(&Activation::new())?;
607    /// assert_eq!(result, Value::List(vec![Value::Int(2), Value::Int(3)]));
608    /// 
609    /// // List sorting
610    /// let program2 = env.compile("[3, 1, 2].sort()")?;
611    /// let result2 = program2.evaluate(&Activation::new())?;
612    /// assert_eq!(result2, Value::List(vec![Value::Int(1), Value::Int(2), Value::Int(3)]));
613    /// 
614    /// // Generate ranges
615    /// let program3 = env.compile("lists.range(3)")?;
616    /// let result3 = program3.evaluate(&Activation::new())?;
617    /// assert_eq!(result3, Value::List(vec![Value::Int(0), Value::Int(1), Value::Int(2)]));
618    /// # Ok::<(), cel_cxx::Error>(())
619    /// ```
620    pub fn with_ext_lists(mut self, enable: bool) -> Self {
621        self.options.enable_ext_lists = enable;
622        self
623    }
624
625    /// Enables or disables the Math extension.
626    ///
627    /// **Default**: Disabled (`false`)
628    ///
629    /// This extension provides advanced mathematical functions beyond the standard operators,
630    /// including min/max operations, rounding functions, absolute value, sign detection,
631    /// bitwise operations, floating point helpers, and square root. All functions are 
632    /// deterministic and side-effect free.
633    ///
634    /// **Note**: All macros use the 'math' namespace; however, at the time of macro
635    /// expansion the namespace looks just like any other identifier. If you are
636    /// currently using a variable named 'math', the macro will likely work just as
637    /// intended; however, there is some chance for collision.
638    ///
639    /// # Available Functions
640    ///
641         /// ## Min/Max Operations
642     /// | Function | Description | Example |
643     /// |----------|-------------|---------|
644     /// | `math.greatest(...)` | Greatest value from arguments/list | `math.greatest(1,2,3)` → `3` |
645     /// | `math.least(...)` | Least value from arguments/list | `math.least([1,2,3])` → `1` |
646    ///
647    /// ## Absolute Value and Sign
648    /// | Function | Description | Example |
649    /// |----------|-------------|---------|
650    /// | `math.abs(number)` | Absolute value | `math.abs(-5)` → `5` |
651    /// | `math.sign(number)` | Sign (-1, 0, or 1) | `math.sign(-5)` → `-1` |
652    ///
653    /// ## Rounding Functions
654    /// | Function | Description | Example |
655    /// |----------|-------------|---------|
656    /// | `math.ceil(number)` | Round up | `math.ceil(3.14)` → `4.0` |
657    /// | `math.floor(number)` | Round down | `math.floor(3.14)` → `3.0` |
658    /// | `math.round(number)` | Round to nearest | `math.round(3.14)` → `3.0` |
659    /// | `math.trunc(number)` | Truncate decimals | `math.trunc(3.14)` → `3.0` |
660    ///
661    /// ## Bitwise Operations
662    /// | Function | Description | Example |
663    /// |----------|-------------|---------|
664    /// | `math.bitAnd(a,b)` | Bitwise AND | `math.bitAnd(5,3)` → `1` |
665    /// | `math.bitOr(a,b)` | Bitwise OR | `math.bitOr(5,3)` → `7` |
666    /// | `math.bitXor(a,b)` | Bitwise XOR | `math.bitXor(5,3)` → `6` |
667    /// | `math.bitNot(n)` | Bitwise NOT | `math.bitNot(5)` → `-6` |
668    /// | `math.bitShiftLeft(n,bits)` | Left bit shift | `math.bitShiftLeft(5,1)` → `10` |
669    /// | `math.bitShiftRight(n,bits)` | Right bit shift | `math.bitShiftRight(5,1)` → `2` |
670    ///
671    /// ## Floating Point Helpers
672    /// | Function | Description | Example |
673    /// |----------|-------------|---------|
674    /// | `math.isInf(number)` | Check if infinite | `math.isInf(1.0/0.0)` → `true` |
675    /// | `math.isNaN(number)` | Check if NaN | `math.isNaN(0.0/0.0)` → `true` |
676    /// | `math.isFinite(number)` | Check if finite | `math.isFinite(1.2)` → `true` |
677    ///
678    /// ## Square Root
679    /// | Function | Description | Example |
680    /// |----------|-------------|---------|
681    /// | `math.sqrt(number)` | Square root | `math.sqrt(81)` → `9.0` |
682    ///
683    /// # CEL Syntax Impact
684    ///
685    /// When enabled, adds mathematical functions in the `math` namespace:
686    /// - Supports both integer and floating-point operations
687    /// - Bitwise operations work on integer types only
688    /// - Rounding functions return double type
689    /// - Min/max functions preserve input type
690    /// - Floating point helpers work with double type
691    /// - Square root always returns double type
692    ///
693    /// # Examples
694    ///
695    /// ```rust
696    /// use cel_cxx::*;
697    /// 
698    /// let env = Env::builder()
699    ///     .with_ext_math(true)
700    ///     .build()?;
701    /// 
702    /// // Greatest/least operations (macros)
703    /// let program = env.compile("math.greatest(5, 2, 8, 1)")?;
704    /// let result = program.evaluate(&Activation::new())?;
705    /// assert_eq!(result, Value::Int(8));
706    /// 
707    /// let program2 = env.compile("math.least([-42.0, -21.5, -100.0])")?;
708    /// let result2 = program2.evaluate(&Activation::new())?;
709    /// assert_eq!(result2, Value::Double(-100.0));
710    /// 
711         /// // Absolute value
712     /// let program3 = env.compile("math.abs(-5)")?;
713     /// let result3 = program3.evaluate(&Activation::new())?;
714     /// assert_eq!(result3, Value::Int(5));
715    /// 
716    /// // Rounding functions
717    /// let program4 = env.compile("math.ceil(3.14)")?;
718    /// let result4 = program4.evaluate(&Activation::new())?;
719    /// assert_eq!(result4, Value::Double(4.0));
720    /// 
721    /// // Bitwise operations
722    /// let program5 = env.compile("math.bitAnd(5, 3)")?;
723    /// let result5 = program5.evaluate(&Activation::new())?;
724    /// assert_eq!(result5, Value::Int(1));
725    /// 
726    /// // Floating point helpers
727    /// let program6 = env.compile("math.isFinite(1.2)")?;
728    /// let result6 = program6.evaluate(&Activation::new())?;
729    /// assert_eq!(result6, Value::Bool(true));
730    /// 
731    /// // Square root
732    /// let program7 = env.compile("math.sqrt(81)")?;
733    /// let result7 = program7.evaluate(&Activation::new())?;
734    /// assert_eq!(result7, Value::Double(9.0));
735    /// # Ok::<(), cel_cxx::Error>(())
736    /// ```
737    pub fn with_ext_math(mut self, enable: bool) -> Self {
738        self.options.enable_ext_math = enable;
739        self
740    }
741
742    /// Enables or disables the Protocol Buffers (Protobuf) extension.
743    ///
744    /// **Default**: Disabled (`false`)
745    ///
746    /// This provides enhanced support for working with Protocol Buffer messages, particularly
747    /// for accessing and testing proto2 extension fields. Requires proper setup of Protobuf 
748    /// descriptors in the environment.
749    ///
750    /// # Available Functions
751    ///
752    /// | Function | Description | Example |
753    /// |----------|-------------|---------|
754    /// | `proto.getExt(msg, ext)` | Get extension field value | `proto.getExt(msg, my.extension)` |
755    /// | `proto.hasExt(msg, ext)` | Test extension field presence | `proto.hasExt(msg, my.extension)` |
756    ///
757    /// # CEL Syntax Impact
758    ///
759    /// When enabled, adds proto2 extension support:
760    /// - `proto.getExt()` returns extension value or default if not set
761    /// - `proto.hasExt()` returns boolean indicating if extension is explicitly set
762    /// - Extension names must be fully qualified (e.g., `com.example.my_extension`)
763    /// - Uses safe-traversal semantics (no errors on missing fields)
764    /// - Only works with proto2 syntax messages that support extensions
765    ///
766    /// # Examples
767    ///
768    /// ```rust,no_run
769    /// use cel_cxx::*;
770    /// 
771    /// let env = Env::builder()
772    ///     .with_ext_proto(true)
773    ///     .build()?;
774    /// 
775    /// // Access extension field
776    /// let program = env.compile("proto.getExt(my_message, com.example.priority_ext)")?;
777    /// 
778    /// // Test extension presence
779    /// let program2 = env.compile("proto.hasExt(my_message, com.example.priority_ext)")?;
780    /// 
781    /// // Conditional processing based on extensions
782    /// let program3 = env.compile(r#"
783    ///     proto.hasExt(msg, com.example.metadata_ext) ? 
784    ///         proto.getExt(msg, com.example.metadata_ext).value : 
785    ///         "default"
786    /// "#)?;
787    /// # Ok::<(), cel_cxx::Error>(())
788    /// ```
789    pub fn with_ext_proto(mut self, enable: bool) -> Self {
790        self.options.enable_ext_proto = enable;
791        self
792    }
793
794    /// Enables or disables the Regular Expression (Regex) extension.
795    ///
796    /// **Default**: Disabled (`false`)
797    ///
798    /// This extension provides functions for pattern matching on strings using regular expressions,
799    /// including pattern extraction, replacement, and text processing. Requires optional types
800    /// to be enabled for proper operation.
801    ///
802    /// # Available Functions
803    ///
804    /// | Function | Description | Example |
805    /// |----------|-------------|---------|
806    /// | `regex.extract(text, pattern)` | Extract first match (optional) | `regex.extract('hello', 'h(.*)o')` → `optional('ell')` |
807    /// | `regex.extractAll(text, pattern)` | Extract all matches | `regex.extractAll('a1 b2', '\\d+')` → `['1', '2']` |
808    /// | `regex.replace(text, pattern, replacement)` | Replace all matches | `regex.replace('hello', 'l', 'x')` → `'hexxo'` |
809    /// | `regex.replace(text, pattern, replacement, count)` | Replace up to count | `regex.replace('hello', 'l', 'x', 1)` → `'hexlo'` |
810    ///
811    /// # CEL Syntax Impact
812    ///
813    /// When enabled, adds regex functions in the `regex` namespace:
814    /// - `regex.extract()` returns `optional<string>` (requires optional types)
815    /// - Supports 0 or 1 capture groups only (error for multiple groups)
816    /// - Uses standard regex syntax with proper escaping
817    /// - Replacement supports capture group references (`\1`, `\2`, etc.)
818    /// - Count parameter in replace: 0=no replacement, negative=replace all
819    ///
820    /// # Examples
821    ///
822    /// ```rust
823    /// use cel_cxx::*;
824    /// 
825    /// let env = Env::builder()
826    ///     .with_ext_regex(true)
827    ///     .with_optional(true)  // Required for regex.extract
828    ///     .build()?;
829    /// 
830    /// // Pattern extraction
831    /// let program = env.compile(r#"regex.extract('hello world', 'hello (.*)')"#)?;
832    /// 
833    /// // Extract all matches
834    /// let program2 = env.compile(r#"regex.extractAll('id:123, id:456', 'id:(\\d+)')"#)?;
835    /// 
836    /// // Pattern replacement with capture groups
837    /// let program3 = env.compile(r#"regex.replace('John Doe', '(\\w+) (\\w+)', r'\2, \1')"#)?;
838    /// # Ok::<(), cel_cxx::Error>(())
839    /// ```
840    pub fn with_ext_regex(mut self, enable: bool) -> Self {
841        self.options.enable_ext_regex = enable;
842        self
843    }
844
845    /// Enables or disables the Regular Expression (RE) extension.
846    ///
847    /// **Default**: Disabled (`false`)
848    ///
849    /// This extension provides C++ specific regular expression functions built on the RE2 library,
850    /// offering additional pattern matching capabilities with different semantics than the standard
851    /// regex extension. This is specific to the C++ CEL implementation.
852    ///
853    /// # Available Functions
854    ///
855    /// | Function | Description | Example |
856    /// |----------|-------------|---------|
857    /// | `re.extract(text, pattern, rewrite)` | Extract and rewrite with pattern | `re.extract('Hello World', r'(\\w+) (\\w+)', r'\\2, \\1')` |
858    /// | `re.capture(text, pattern)` | Capture first group | `re.capture('john@example.com', r'([^@]+)@')` |
859    /// | `re.captureN(text, pattern)` | Capture all groups as map | `re.captureN('2023-12-25', r'(\\d{4})-(\\d{2})-(\\d{2})')` |
860    ///
861    /// # CEL Syntax Impact
862    ///
863    /// When enabled, adds RE2-based regex functions in the `re` namespace:
864    /// - `re.extract()` performs extraction and rewriting in one operation
865    /// - `re.capture()` returns string of first capture group
866    /// - `re.captureN()` returns map with numbered/named capture groups
867    /// - Uses RE2 library for consistent performance and safety
868    /// - Supports named capture groups in `captureN()`
869    ///
870    /// # Examples
871    ///
872    /// ```rust
873    /// use cel_cxx::*;
874    /// 
875    /// let env = Env::builder()
876    ///     .with_ext_re(true)
877    ///     .build()?;
878    /// 
879    /// // Extract and rewrite
880    /// let program = env.compile(r#"re.extract('Hello World', r'(\w+) (\w+)', r'\2, \1')"#)?;
881    /// 
882    /// // Capture first group
883    /// let program2 = env.compile(r#"re.capture('john@example.com', r'([^@]+)@')"#)?;
884    /// 
885    /// // Capture all groups
886    /// let program3 = env.compile(r#"re.captureN('2023-12-25', r'(\d{4})-(\d{2})-(\d{2})')"#)?;
887    /// # Ok::<(), cel_cxx::Error>(())
888    /// ```
889    pub fn with_ext_re(mut self, enable: bool) -> Self {
890        self.options.enable_ext_re = enable;
891        self
892    }
893
894    /// Enables or disables the Sets extension.
895    ///
896    /// **Default**: Disabled (`false`)
897    ///
898    /// This extension provides functions for set-based operations on lists, such as containment
899    /// checking, equivalence testing, and intersection detection. Note that CEL does not have 
900    /// a native `set` type; these functions treat lists as sets.
901    ///
902    /// # Available Functions
903    ///
904    /// | Function | Description | Example |
905    /// |----------|-------------|---------|
906    /// | `sets.contains(list1, list2)` | Check if list1 contains all elements of list2 | `sets.contains([1,2,3], [2,3])` → `true` |
907    /// | `sets.equivalent(list1, list2)` | Check if lists are set equivalent | `sets.equivalent([1,2,3], [3,2,1])` → `true` |
908    /// | `sets.intersects(list1, list2)` | Check if lists have common elements | `sets.intersects([1,2], [2,3])` → `true` |
909    ///
910    /// # CEL Syntax Impact
911    ///
912    /// When enabled, adds set operations in the `sets` namespace:
913    /// - Treats lists as sets (order and duplicates don't matter for equivalence)
914    /// - Uses standard CEL equality for element comparison
915    /// - Supports type coercion (e.g., `1`, `1.0`, `1u` are considered equal)
916    /// - Empty list operations: `contains([], [])` → `true`, `intersects([], [])` → `false`
917    /// - Works with any comparable types
918    ///
919    /// # Examples
920    ///
921    /// ```rust
922    /// use cel_cxx::*;
923    /// 
924    /// let env = Env::builder()
925    ///     .with_ext_sets(true)
926    ///     .build()?;
927    /// 
928    /// // Set containment
929    /// let program = env.compile("sets.contains([1, 2, 3, 4], [2, 3])")?;
930    /// let result = program.evaluate(&Activation::new())?;
931    /// assert_eq!(result, Value::Bool(true));
932    /// 
933    /// // Set equivalence
934    /// let program2 = env.compile("sets.equivalent([1, 2, 3], [3, 2, 1])")?;
935    /// let result2 = program2.evaluate(&Activation::new())?;
936    /// assert_eq!(result2, Value::Bool(true));
937    /// 
938    /// // Set intersection
939    /// let program3 = env.compile("sets.intersects([1, 2], [2, 3])")?;
940    /// let result3 = program3.evaluate(&Activation::new())?;
941    /// assert_eq!(result3, Value::Bool(true));
942    /// # Ok::<(), cel_cxx::Error>(())
943    /// ```
944    pub fn with_ext_sets(mut self, enable: bool) -> Self {
945        self.options.enable_ext_sets = enable;
946        self
947    }
948
949    /// Enables or disables the Strings extension.
950    ///
951    /// **Default**: Disabled (`false`)
952    ///
953    /// This extension provides additional functions for string manipulation, including character
954    /// access, searching, extraction, case conversion, formatting, and advanced text processing
955    /// operations that go beyond the basic string operations in the standard library.
956    ///
957    /// # Available Functions
958    ///
959    /// | Function | Description | Example |
960    /// |----------|-------------|---------|
961    /// | `string.charAt(index)` | Get character at index | `'hello'.charAt(1)` → `'e'` |
962    /// | `string.indexOf(substring)` | Find first occurrence | `'hello'.indexOf('l')` → `2` |
963    /// | `string.indexOf(substring, start)` | Find from start position | `'hello'.indexOf('l', 3)` → `3` |
964    /// | `string.lastIndexOf(substring)` | Find last occurrence | `'hello'.lastIndexOf('l')` → `3` |
965    /// | `string.substring(start)` | Extract from start to end | `'hello'.substring(1)` → `'ello'` |
966    /// | `string.substring(start, end)` | Extract substring | `'hello'.substring(1, 4)` → `'ell'` |
967    /// | `strings.quote(string)` | Quote string for CEL | `strings.quote('hello')` → `'"hello"'` |
968    /// | `string.trim()` | Remove whitespace | `' hello '.trim()` → `'hello'` |
969    /// | `list.join(separator)` | Join strings | `['a','b'].join(',')` → `'a,b'` |
970    /// | `string.split(separator)` | Split string | `'a,b,c'.split(',')` → `['a','b','c']` |
971    /// | `string.lowerAscii()` | Convert to lowercase | `'HELLO'.lowerAscii()` → `'hello'` |
972    /// | `string.upperAscii()` | Convert to uppercase | `'hello'.upperAscii()` → `'HELLO'` |
973    /// | `string.replace(old, new)` | Replace all occurrences | `'hello'.replace('l','x')` → `'hexxo'` |
974    /// | `string.replace(old, new, count)` | Replace up to count | `'hello'.replace('l','x',1)` → `'hexlo'` |
975    /// | `string.format(args)` | Printf-style formatting | `'Hello %s'.format(['World'])` → `'Hello World'` |
976    /// | `string.reverse()` | Reverse string | `'hello'.reverse()` → `'olleh'` |
977    ///
978    /// # CEL Syntax Impact
979    ///
980    /// When enabled, adds advanced string manipulation capabilities:
981    /// - Zero-based indexing for character access and substring operations
982    /// - Safe out-of-bounds handling (empty string for invalid indices)
983    /// - ASCII-only case conversion (Unicode characters unchanged)
984    /// - Printf-style format placeholders: `%s`, `%d`, `%f`, `%.Nf`
985    /// - Efficient string processing with immutable operations
986    ///
987    /// # Examples
988    ///
989    /// ```rust
990    /// use cel_cxx::*;
991    /// 
992    /// let env = Env::builder()
993    ///     .with_ext_strings(true)
994    ///     .build()?;
995    /// 
996    /// // String searching and extraction
997    /// let program = env.compile("'hello world'.substring('hello world'.indexOf(' ') + 1)")?;
998    /// let result = program.evaluate(&Activation::new())?;
999    /// assert_eq!(result, Value::String("world".into()));
1000    /// 
1001    /// // String formatting
1002    /// let program2 = env.compile("'Hello, %s!'.format(['Alice'])")?;
1003    /// let result2 = program2.evaluate(&Activation::new())?;
1004    /// assert_eq!(result2, Value::String("Hello, Alice!".into()));
1005    /// 
1006    /// // String processing pipeline
1007    /// let program3 = env.compile("'  HELLO WORLD  '.trim().lowerAscii().replace(' ', '_')")?;
1008    /// let result3 = program3.evaluate(&Activation::new())?;
1009    /// assert_eq!(result3, Value::String("hello_world".into()));
1010    /// # Ok::<(), cel_cxx::Error>(())
1011    /// ```
1012    pub fn with_ext_strings(mut self, enable: bool) -> Self {
1013        self.options.enable_ext_strings = enable;
1014        self
1015    }
1016
1017    /// Enables or disables the select optimization extension.
1018    ///
1019    /// **Default**: Disabled (`false`)
1020    ///
1021    /// This is an optimization that can improve the performance of `select` expressions
1022    /// (field access) by transforming them at compile time. It does not introduce new
1023    /// user-visible functions but can change the evaluation cost of field access operations.
1024    ///
1025    /// # CEL Syntax Impact
1026    ///
1027    /// When enabled, provides compile-time optimizations for:
1028    /// - Message field access operations
1029    /// - Map key access patterns
1030    /// - Nested field selection chains
1031    /// - No new syntax or functions are added
1032    /// - Transparent performance improvements
1033    ///
1034    /// # Examples
1035    ///
1036    /// ```rust
1037    /// use cel_cxx::*;
1038    /// 
1039    /// let env = Env::builder()
1040    ///     .with_ext_select_optimization(true)
1041    ///     .build()?;
1042    /// 
1043    /// // Field access operations may be optimized
1044    /// let program = env.compile("user.profile.settings.theme")?;
1045    /// 
1046    /// // Map access patterns may be optimized  
1047    /// let program2 = env.compile("config['database']['host']")?;
1048    /// # Ok::<(), cel_cxx::Error>(())
1049    /// ```
1050    pub fn with_ext_select_optimization(mut self, enable: bool) -> Self {
1051        self.options.enable_ext_select_optimization = enable;
1052        self
1053    }
1054
1055    /// Registers a CEL macro for compile-time expression expansion.
1056    ///
1057    /// Macros enable custom syntactic sugar and expression transformations that
1058    /// execute during the compilation phase, before type checking and evaluation.
1059    /// This allows you to extend CEL's syntax without modifying the parser.
1060    ///
1061    /// # Macro Registration Process
1062    ///
1063    /// When you register a macro:
1064    /// 1. The macro's unique key (based on name, style, and arity) is computed
1065    /// 2. The system checks for conflicts with existing macros
1066    /// 3. If no conflict exists, the macro is stored in the environment
1067    /// 4. Future compilations will invoke the macro when matching expressions are encountered
1068    ///
1069    /// # Macro Types
1070    ///
1071    /// You can register two types of macros:
1072    /// - **Global macros**: Invoked as functions, e.g., `all(list, x, x > 0)`
1073    /// - **Receiver macros**: Invoked as methods, e.g., `list.filter(x, x > 0)`
1074    ///
1075    /// Both can accept fixed or variable numbers of arguments.
1076    ///
1077    /// # Errors
1078    ///
1079    /// Returns an error if:
1080    /// - A macro with the same key (name, style, and arity) is already registered
1081    ///
1082    /// # Examples
1083    ///
1084    /// ## Registering a global macro
1085    ///
1086    /// ```rust,no_run
1087    /// # use cel_cxx::{EnvBuilder, Error};
1088    /// # use cel_cxx::macros::Macro;
1089    /// # fn example() -> Result<(), Error> {
1090    /// // Create a macro that expands not_zero(x) to x != 0
1091    /// let not_zero = Macro::new_global("not_zero", 1, |factory, mut args| {
1092    ///     let arg = args.pop()?;
1093    ///     Some(factory.new_call("_!=_", &[arg, factory.new_const(0)]))
1094    /// })?;
1095    ///
1096    /// let env = EnvBuilder::new()
1097    ///     .register_macro(not_zero)?
1098    ///     .build()?;
1099    ///
1100    /// // Now "not_zero(value)" in expressions will be expanded to "value != 0"
1101    /// let program = env.compile("not_zero(x)")?;
1102    /// # Ok(())
1103    /// # }
1104    /// ```
1105    ///
1106    /// ## Registering a receiver macro
1107    ///
1108    /// ```rust,no_run
1109    /// # use cel_cxx::{EnvBuilder, Error};
1110    /// # use cel_cxx::macros::Macro;
1111    /// # fn example() -> Result<(), Error> {
1112    /// // Create a macro for optional chaining: target.get_or(default)
1113    /// let get_or = Macro::new_receiver("get_or", 1, |factory, target, mut args| {
1114    ///     let default_val = args.pop()?;
1115    ///     // Expand to: target != null ? target : default_val
1116    ///     let null_check = factory.new_call("_!=_", &[
1117    ///         target.clone(),
1118    ///         factory.new_const(())
1119    ///     ]);
1120    ///     Some(factory.new_call("_?_:_", &[null_check, target, default_val]))
1121    /// })?;
1122    ///
1123    /// let env = EnvBuilder::new()
1124    ///     .register_macro(get_or)?
1125    ///     .build()?;
1126    ///
1127    /// // Now "value.get_or(0)" will expand to null-safe access
1128    /// let program = env.compile("value.get_or(0)")?;
1129    /// # Ok(())
1130    /// # }
1131    /// ```
1132    ///
1133    /// ## Multiple macros
1134    ///
1135    /// ```rust,no_run
1136    /// # use cel_cxx::{EnvBuilder, Error};
1137    /// # use cel_cxx::macros::Macro;
1138    /// # fn example() -> Result<(), Error> {
1139    /// let macro1 = Macro::new_global("custom_op", 2, |factory, args| {
1140    ///     // Implementation
1141    ///     None
1142    /// })?;
1143    ///
1144    /// let macro2 = Macro::new_receiver("custom_method", 1, |factory, target, args| {
1145    ///     // Implementation
1146    ///     None
1147    /// })?;
1148    ///
1149    /// let env = EnvBuilder::new()
1150    ///     .register_macro(macro1)?
1151    ///     .register_macro(macro2)?
1152    ///     .build()?;
1153    /// # Ok(())
1154    /// # }
1155    /// ```
1156    pub fn register_macro(mut self, m: Macro) -> Result<Self, Error> {
1157        let key = String::from_utf8_lossy(m.key()).to_string();
1158        if !self.macros.insert(m) {
1159            return Err(Error::invalid_argument(format!("macro already registered: {}", key)));
1160        }
1161        Ok(self)
1162    }
1163
1164    /// Registers a function (either global or member).
1165    ///
1166    /// This method allows you to register custom functions that can be called
1167    /// from CEL expressions. The function can be either a global function or
1168    /// a member function of a type.
1169    ///
1170    /// # Function Registration Process
1171    ///
1172    /// When you register a function, the system:
1173    /// 1. Extracts type information from the function signature
1174    /// 2. Creates type-safe conversion wrappers
1175    /// 3. Stores both the type signature and implementation
1176    /// 4. Updates the function marker type to track sync/async status
1177    ///
1178    /// # Zero-Annotation Benefits
1179    ///
1180    /// Functions are registered without explicit type annotations:
1181    /// - Argument types are automatically inferred
1182    /// - Return types are automatically determined
1183    /// - Error handling is automatically supported for `Result<T, E>` returns
1184    /// - Reference parameters like `&str` are handled safely
1185    ///
1186    /// # Arguments
1187    ///
1188    /// * `name` - The name of the function as it will appear in CEL expressions
1189    /// * `member` - Whether this is a member function (`true`) or global function (`false`)
1190    /// * `f` - The function implementation (function pointer, closure, etc.)
1191    ///
1192    /// # Type Parameters
1193    ///
1194    /// * `F` - The function implementation type
1195    /// * `Ffm` - The function marker type (sync/async) inferred from the function
1196    /// * `Args` - The argument tuple type (automatically inferred)
1197    ///
1198    /// # Returns
1199    ///
1200    /// A new `EnvBuilder` with updated function marker type. If this is the first
1201    /// async function registered, the marker changes from `()` to `Async`.
1202    ///
1203    /// # Member vs Global Functions
1204    ///
1205    /// ## Global Functions
1206    /// Called as `function_name(args...)`:
1207    /// ```text
1208    /// max(a, b)           // max function with two arguments
1209    /// calculate(x, y, z)  // calculate function with three arguments
1210    /// ```
1211    ///
1212    /// ## Member Functions  
1213    /// Called as `object.method(args...)`:
1214    /// ```text
1215    /// text.contains(substring)    // contains method on string
1216    /// list.size()                // size method on list
1217    /// ```
1218    ///
1219    /// # Function Signature Support
1220    ///
1221    /// Supports various function signatures:
1222    /// - **Simple functions**: `fn(T) -> U`
1223    /// - **Functions with errors**: `fn(T) -> Result<U, E>`
1224    /// - **Reference parameters**: `fn(&str, i64) -> String`
1225    /// - **Multiple parameters**: Up to 10 parameters supported
1226    /// - **Closures**: Move closures that capture environment
1227    ///
1228    /// # Errors
1229    ///
1230    /// Returns [`Error`] if:
1231    /// - Function name conflicts with existing registration
1232    /// - Function signature is invalid or unsupported
1233    /// - Type inference fails
1234    ///
1235    /// # Examples
1236    ///
1237    /// ## Basic Functions
1238    ///
1239    /// ```rust
1240    /// use cel_cxx::*;
1241    ///
1242    /// let builder = Env::builder()
1243    ///     .register_function("add", false, |a: i64, b: i64| a + b)?
1244    ///     .register_function("greet", false, |name: &str| format!("Hello, {}!", name))?;
1245    /// # Ok::<(), cel_cxx::Error>(())
1246    /// ```
1247    ///
1248    /// ## Member Functions
1249    ///
1250    /// ```rust
1251    /// use cel_cxx::*;
1252    ///
1253    /// let builder = Env::builder()
1254    ///     .register_function("contains", true, |text: &str, substr: &str| text.contains(substr))?
1255    ///     .register_function("length", true, |text: &str| text.len() as i64)?;
1256    ///
1257    /// // Usage in expressions:
1258    /// // text.contains("hello")
1259    /// // text.length()
1260    /// # Ok::<(), cel_cxx::Error>(())
1261    /// ```
1262    ///
1263    /// ## Functions with Error Handling
1264    ///
1265    /// ```rust
1266    /// use cel_cxx::*;
1267    ///
1268    /// let builder = Env::builder()
1269    ///     .register_function("divide", false, |a: f64, b: f64| -> Result<f64, Error> {
1270    ///         if b == 0.0 {
1271    ///             Err(Error::invalid_argument("division by zero"))
1272    ///         } else {
1273    ///             Ok(a / b)
1274    ///         }
1275    ///     })?;
1276    /// # Ok::<(), cel_cxx::Error>(())
1277    /// ```
1278    ///
1279    /// ## Closures with Captured Data
1280    ///
1281    /// ```rust
1282    /// use cel_cxx::*;
1283    ///
1284    /// let multiplier = 5;
1285    /// let threshold = 100.0;
1286    ///
1287    /// let builder = Env::builder()
1288    ///     .register_function("scale", false, move |x: i64| x * multiplier)?
1289    ///     .register_function("check_limit", false, move |value: f64| value < threshold)?;
1290    /// # Ok::<(), cel_cxx::Error>(())
1291    /// ```
1292    pub fn register_function<F, Ffm, Args>(
1293        mut self,
1294        name: impl Into<String>,
1295        member: bool,
1296        f: F,
1297    ) -> Result<EnvBuilder<'f, <Ffm as FnMarkerAggr<Fm>>::Output, Rm>, Error>
1298    where
1299        F: IntoFunction<'f, Ffm, Args>,
1300        Ffm: FnMarker + FnMarkerAggr<Fm>,
1301        Args: Arguments,
1302    {
1303        self.function_registry.register(name, member, f)?;
1304
1305        Ok(EnvBuilder {
1306            macros: self.macros,
1307            function_registry: self.function_registry,
1308            variable_registry: self.variable_registry,
1309            options: self.options,
1310            _fn_marker: std::marker::PhantomData,
1311            _rt_marker: std::marker::PhantomData,
1312        })
1313    }
1314
1315    /// Registers a member function.
1316    ///
1317    /// This is a convenience method for registering member functions, equivalent to
1318    /// calling `register_function(name, true, f)`. Member functions are called using
1319    /// dot notation in CEL expressions: `object.method(args...)`.
1320    ///
1321    /// # Arguments
1322    ///
1323    /// * `name` - The method name as it will appear in CEL expressions
1324    /// * `f` - The function implementation
1325    ///
1326    /// # Member Function Semantics
1327    ///
1328    /// Member functions in CEL follow these patterns:
1329    /// - First parameter is the "receiver" (the object before the dot)
1330    /// - Additional parameters become method arguments
1331    /// - Called as `receiver.method(arg1, arg2, ...)`
1332    ///
1333    /// # Examples
1334    ///
1335    /// ## String Methods
1336    ///
1337    /// ```rust
1338    /// use cel_cxx::*;
1339    ///
1340    /// let builder = Env::builder()
1341    ///     .register_member_function("upper", |s: &str| s.to_uppercase())?
1342    ///     .register_member_function("contains", |s: &str, substr: &str| s.contains(substr))?
1343    ///     .register_member_function("repeat", |s: &str, n: i64| s.repeat(n as usize))?;
1344    ///
1345    /// // Usage in expressions:
1346    /// // "hello".upper()           -> "HELLO"
1347    /// // "hello world".contains("world") -> true
1348    /// // "abc".repeat(3)           -> "abcabcabc"
1349    /// # Ok::<(), cel_cxx::Error>(())
1350    /// ```
1351    ///
1352    /// ## Numeric Methods
1353    ///
1354    /// ```rust
1355    /// use cel_cxx::*;
1356    ///
1357    /// let builder = Env::builder()
1358    ///     .register_member_function("abs", |x: f64| x.abs())?
1359    ///     .register_member_function("pow", |x: f64, exp: f64| x.powf(exp))?;
1360    ///
1361    /// // Usage in expressions:
1362    /// // (-5.5).abs()     -> 5.5
1363    /// // (2.0).pow(3.0)   -> 8.0
1364    /// # Ok::<(), cel_cxx::Error>(())
1365    /// ```
1366    pub fn register_member_function<F, Ffm, Args>(
1367        mut self,
1368        name: impl Into<String>,
1369        f: F,
1370    ) -> Result<EnvBuilder<'f, <Ffm as FnMarkerAggr<Fm>>::Output, Rm>, Error>
1371    where
1372        F: IntoFunction<'f, Ffm, Args>,
1373        Ffm: FnMarker + FnMarkerAggr<Fm>,
1374        Args: Arguments + NonEmptyArguments,
1375    {
1376        self.function_registry.register_member(name, f)?;
1377
1378        Ok(EnvBuilder {
1379            macros: self.macros,
1380            function_registry: self.function_registry,
1381            variable_registry: self.variable_registry,
1382            options: self.options,
1383            _fn_marker: std::marker::PhantomData,
1384            _rt_marker: std::marker::PhantomData,
1385        })
1386    }
1387
1388    /// Registers a global function.
1389    ///
1390    /// This is a convenience method for registering global functions, equivalent to
1391    /// calling `register_function(name, false, f)`. Global functions are called directly
1392    /// by name in CEL expressions: `function_name(args...)`.
1393    ///
1394    /// # Arguments
1395    ///
1396    /// * `name` - The function name as it will appear in CEL expressions
1397    /// * `f` - The function implementation
1398    ///
1399    /// # Global Function Characteristics
1400    ///
1401    /// Global functions:
1402    /// - Are called directly by name without a receiver object
1403    /// - Can have 0 to 10 parameters
1404    /// - Support all CEL-compatible parameter and return types
1405    /// - Can capture environment variables (for closures)
1406    ///
1407    /// # Function Naming Guidelines
1408    ///
1409    /// - Use clear, descriptive names: `calculate_tax`, `format_date`
1410    /// - Follow CEL naming conventions (snake_case is recommended)
1411    /// - Avoid conflicts with built-in CEL functions
1412    /// - Consider namespacing for domain-specific functions: `math_sqrt`, `string_trim`
1413    ///
1414    /// # Examples
1415    ///
1416    /// ## Mathematical Functions
1417    ///
1418    /// ```rust
1419    /// use cel_cxx::*;
1420    ///
1421    /// let builder = Env::builder()
1422    ///     .register_global_function("add", |a: i64, b: i64| a + b)?
1423    ///     .register_global_function("multiply", |a: f64, b: f64| a * b)?
1424    ///     .register_global_function("max", |a: i64, b: i64| if a > b { a } else { b })?;
1425    ///
1426    /// // Usage in expressions:
1427    /// // add(10, 20)          -> 30
1428    /// // multiply(2.5, 4.0)   -> 10.0
1429    /// // max(15, 8)           -> 15
1430    /// # Ok::<(), cel_cxx::Error>(())
1431    /// ```
1432    ///
1433    /// ## String Processing Functions
1434    ///
1435    /// ```rust
1436    /// use cel_cxx::*;
1437    ///
1438    /// let builder = Env::builder()
1439    ///     .register_global_function("concat", |a: &str, b: &str| format!("{}{}", a, b))?
1440    ///     .register_global_function("trim_prefix", |s: &str, prefix: &str| {
1441    ///         s.strip_prefix(prefix).unwrap_or(s).to_string()
1442    ///     })?;
1443    ///
1444    /// // Usage in expressions:
1445    /// // concat("Hello, ", "World!")     -> "Hello, World!"
1446    /// // trim_prefix("prefixed_text", "prefixed_")  -> "text"
1447    /// # Ok::<(), cel_cxx::Error>(())
1448    /// ```
1449    ///
1450    /// ## Business Logic Functions
1451    ///
1452    /// ```rust
1453    /// use cel_cxx::*;
1454    ///
1455    /// let builder = Env::builder()
1456    ///     .register_global_function("calculate_discount", |price: f64, rate: f64| {
1457    ///         price * (1.0 - rate.min(1.0).max(0.0))
1458    ///     })?
1459    ///     .register_global_function("is_valid_email", |email: &str| {
1460    ///         email.contains('@') && email.contains('.')
1461    ///     })?;
1462    ///
1463    /// // Usage in expressions:
1464    /// // calculate_discount(100.0, 0.15)     -> 85.0
1465    /// // is_valid_email("user@domain.com")   -> true
1466    /// # Ok::<(), cel_cxx::Error>(())
1467    /// ```
1468    ///
1469    /// ## Functions with Complex Logic
1470    ///
1471    /// ```rust
1472    /// use cel_cxx::*;
1473    /// use std::collections::HashMap;
1474    ///
1475    /// // Function that processes collections
1476    /// let builder = Env::builder()
1477    ///     .register_global_function("sum_positive", |numbers: Vec<i64>| {
1478    ///         numbers.iter().filter(|&x| *x > 0).sum::<i64>()
1479    ///     })?;
1480    ///
1481    /// // Usage in expressions:
1482    /// // sum_positive([1, -2, 3, -4, 5])  -> 9
1483    /// # Ok::<(), cel_cxx::Error>(())
1484    /// ```
1485    pub fn register_global_function<F, Ffm, Args>(
1486        mut self,
1487        name: impl Into<String>,
1488        f: F,
1489    ) -> Result<EnvBuilder<'f, <Ffm as FnMarkerAggr<Fm>>::Output, Rm>, Error>
1490    where
1491        F: IntoFunction<'f, Ffm, Args>,
1492        Ffm: FnMarker + FnMarkerAggr<Fm>,
1493        Args: Arguments,
1494    {
1495        self.function_registry.register_global(name, f)?;
1496
1497        Ok(EnvBuilder {
1498            macros: self.macros,
1499            function_registry: self.function_registry,
1500            variable_registry: self.variable_registry,
1501            options: self.options,
1502            _fn_marker: std::marker::PhantomData,
1503            _rt_marker: std::marker::PhantomData,
1504        })
1505    }
1506
1507    /// Declares a function signature without providing an implementation.
1508    ///
1509    /// This is useful when you want to declare that a function exists for
1510    /// type checking purposes, but will provide the implementation later
1511    /// via activation bindings.
1512    ///
1513    /// # Arguments
1514    ///
1515    /// * `name` - The name of the function
1516    /// * `member` - Whether this is a member function (`true`) or global function (`false`)
1517    ///
1518    /// # Type Parameters
1519    ///
1520    /// * `D` - The function declaration type that specifies the signature
1521    pub fn declare_function<D>(
1522        mut self,
1523        name: impl Into<String>,
1524        member: bool,
1525    ) -> Result<Self, Error>
1526    where
1527        D: FunctionDecl,
1528    {
1529        self.function_registry.declare::<D>(name, member)?;
1530        Ok(EnvBuilder {
1531            macros: self.macros,
1532            function_registry: self.function_registry,
1533            variable_registry: self.variable_registry,
1534            options: self.options,
1535            _fn_marker: std::marker::PhantomData,
1536            _rt_marker: std::marker::PhantomData,
1537        })
1538    }
1539
1540    /// Declares a member function signature without providing an implementation.
1541    ///
1542    /// # Arguments
1543    ///
1544    /// * `name` - The name of the member function
1545    ///
1546    /// # Type Parameters
1547    ///
1548    /// * `D` - The function declaration type that specifies the signature.
1549    ///   Must implement [`FunctionDecl`] and [`FunctionDeclWithNonEmptyArguments`] to ensure
1550    ///   the member function has at least one argument (the receiver object).
1551    pub fn declare_member_function<D>(mut self, name: impl Into<String>) -> Result<Self, Error>
1552    where
1553        D: FunctionDecl + FunctionDeclWithNonEmptyArguments,
1554    {
1555        self.function_registry.declare_member::<D>(name)?;
1556        Ok(EnvBuilder {
1557            macros: self.macros,
1558            function_registry: self.function_registry,
1559            variable_registry: self.variable_registry,
1560            options: self.options,
1561            _fn_marker: std::marker::PhantomData,
1562            _rt_marker: std::marker::PhantomData,
1563        })
1564    }
1565
1566    /// Declares a global function signature without providing an implementation.
1567    ///
1568    /// # Arguments
1569    ///
1570    /// * `name` - The name of the global function
1571    ///
1572    /// # Type Parameters
1573    ///
1574    /// * `D` - The function declaration type that specifies the signature
1575    pub fn declare_global_function<D>(mut self, name: impl Into<String>) -> Result<Self, Error>
1576    where
1577        D: FunctionDecl,
1578    {
1579        self.function_registry.declare_global::<D>(name)?;
1580        Ok(EnvBuilder {
1581            macros: self.macros,
1582            function_registry: self.function_registry,
1583            variable_registry: self.variable_registry,
1584            options: self.options,
1585            _fn_marker: std::marker::PhantomData,
1586            _rt_marker: std::marker::PhantomData,
1587        })
1588    }
1589
1590    /// Defines a constant value that can be referenced in expressions.
1591    ///
1592    /// Constants are immutable values that are resolved at compile time.
1593    ///
1594    /// # Arguments
1595    ///
1596    /// * `name` - The name of the constant
1597    /// * `value` - The constant value
1598    ///
1599    /// # Examples
1600    ///
1601    /// ```rust,no_run
1602    /// use cel_cxx::*;
1603    ///
1604    /// let builder = Env::builder()
1605    ///     .define_constant("PI", 3.14159)
1606    ///     .unwrap();
1607    /// # Ok::<(), cel_cxx::Error>(())
1608    /// ```
1609    pub fn define_constant<T>(mut self, name: impl Into<String>, value: T) -> Result<Self, Error>
1610    where
1611        T: IntoConstant,
1612    {
1613        self.variable_registry.define_constant(name, value)?;
1614        Ok(EnvBuilder {
1615            macros: self.macros,
1616            function_registry: self.function_registry,
1617            variable_registry: self.variable_registry,
1618            options: self.options,
1619            _fn_marker: std::marker::PhantomData,
1620            _rt_marker: std::marker::PhantomData,
1621        })
1622    }
1623
1624    /// Declares a variable of a specific type.
1625    ///
1626    /// This declares that a variable of the given name and type may be
1627    /// provided during evaluation. The actual value must be bound in
1628    /// the activation when evaluating expressions.
1629    ///
1630    /// # Arguments
1631    ///
1632    /// * `name` - The name of the variable
1633    ///
1634    /// # Type Parameters
1635    ///
1636    /// * `T` - The type of the variable
1637    ///
1638    /// # Examples
1639    ///
1640    /// ```rust,no_run
1641    /// use cel_cxx::*;
1642    ///
1643    /// let builder = Env::builder()
1644    ///     .declare_variable::<String>("user_name")?
1645    ///     .declare_variable::<i64>("age")?;
1646    ///
1647    /// # Ok::<(), cel_cxx::Error>(())
1648    /// ```
1649    pub fn declare_variable<T>(mut self, name: impl Into<String>) -> Result<Self, Error>
1650    where
1651        T: TypedValue,
1652    {
1653        self.variable_registry.declare::<T>(name)?;
1654        Ok(EnvBuilder {
1655            macros: self.macros,
1656            function_registry: self.function_registry,
1657            variable_registry: self.variable_registry,
1658            options: self.options,
1659            _fn_marker: std::marker::PhantomData,
1660            _rt_marker: std::marker::PhantomData,
1661        })
1662    }
1663
1664    /// Builds the environment from the configured builder.
1665    ///
1666    /// This method consumes the builder and creates the final [`Env`] instance
1667    /// that can be used to compile CEL expressions.
1668    ///
1669    /// # Returns
1670    ///
1671    /// Returns a [`Result`] containing the built [`Env`] or an [`Error`] if
1672    /// the environment could not be created.
1673    ///
1674    /// # Examples
1675    ///
1676    /// ```rust,no_run
1677    /// use cel_cxx::*;
1678    ///
1679    /// let env = Env::builder()
1680    ///     .declare_variable::<String>("name")?
1681    ///     .build()?;
1682    /// # Ok::<(), cel_cxx::Error>(())
1683    /// ```
1684    ///
1685    /// # Errors
1686    ///
1687    /// Returns an error if the environment configuration is invalid or
1688    /// if the underlying CEL environment cannot be created.
1689    pub fn build(self) -> Result<Env<'f, Fm, Rm>, Error> {
1690        let inner = EnvInner::new_with_registries(self.macros, self.function_registry, self.variable_registry, self.options)
1691            .map_err(|ffi_status| Error::from(&ffi_status))?;
1692        let env = Env {
1693            inner: Arc::new(inner),
1694            _fn_marker: self._fn_marker,
1695            _rt_marker: self._rt_marker,
1696        };
1697        Ok(env)
1698    }
1699}
1700
1701#[cfg(feature = "async")]
1702#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
1703const _: () = {
1704    use crate::r#async::*;
1705
1706    impl<'f, Rm: RuntimeMarker> Env<'f, (), Rm> {
1707        /// Forces conversion to an async environment.
1708        ///
1709        /// This method converts a synchronous environment to an asynchronous one,
1710        /// allowing it to work with async functions and evaluation.
1711        ///
1712        /// # Type Parameters
1713        ///
1714        /// * `Rt` - The async runtime type to use
1715        ///
1716        /// # Examples
1717        ///
1718        /// ```rust,no_run
1719        /// # #[cfg(feature = "async")]
1720        /// # {
1721        /// use cel_cxx::*;
1722        ///
1723        /// let sync_env = Env::builder().build()?;
1724        /// let async_env = sync_env.force_async();
1725        /// # }
1726        /// # Ok::<(), cel_cxx::Error>(())
1727        /// ```
1728        pub fn force_async(self) -> Env<'f, Async, Rm> {
1729            Env {
1730                inner: self.inner,
1731                _fn_marker: std::marker::PhantomData,
1732                _rt_marker: std::marker::PhantomData,
1733            }
1734        }
1735    }
1736
1737    impl<'f, Rm: RuntimeMarker> EnvBuilder<'f, (), Rm> {
1738        /// Forces conversion to an async environment builder.
1739        ///
1740        /// This method converts a synchronous environment builder to an asynchronous one,
1741        /// allowing it to register async functions and build async environments.
1742        ///
1743        /// # Examples
1744        ///
1745        /// ```rust,no_run
1746        /// # #[cfg(feature = "async")]
1747        /// # {
1748        /// use cel_cxx::*;
1749        ///
1750        /// let async_builder = Env::builder().force_async();
1751        /// # }
1752        /// ```
1753        pub fn force_async(self) -> EnvBuilder<'f, Async, Rm> {
1754            EnvBuilder {
1755                macros: self.macros,
1756                function_registry: self.function_registry,
1757                variable_registry: self.variable_registry,
1758                options: self.options,
1759                _fn_marker: std::marker::PhantomData,
1760                _rt_marker: std::marker::PhantomData,
1761            }
1762        }
1763    }
1764
1765    impl<'f, Fm: FnMarker> Env<'f, Fm, ()> {
1766        /// Sets the async runtime for this environment.
1767        ///
1768        /// This method specifies which async runtime should be used for
1769        /// asynchronous evaluation of expressions.
1770        ///
1771        /// # Type Parameters
1772        ///
1773        /// * `Rt` - The runtime type to use (must implement [`Runtime`])
1774        ///
1775        /// # Examples
1776        ///
1777        /// ```rust,no_run
1778        /// # #[cfg(feature = "async")]
1779        /// # {
1780        /// use cel_cxx::*;
1781        ///
1782        /// let env = Env::builder()
1783        ///     .build()?
1784        ///     .use_runtime::<Tokio>();
1785        /// # }
1786        /// # Ok::<(), cel_cxx::Error>(())
1787        /// ```
1788        pub fn use_runtime<Rt: Runtime>(self) -> Env<'f, Fm, Rt> {
1789            let inner = self.inner.clone();
1790            Env {
1791                inner,
1792                _fn_marker: self._fn_marker,
1793                _rt_marker: std::marker::PhantomData,
1794            }
1795        }
1796
1797        /// Configures the environment to use the Tokio async runtime.
1798        ///
1799        /// This is a convenience method for setting the runtime to Tokio.
1800        /// Requires the `tokio` feature to be enabled.
1801        ///
1802        /// # Examples
1803        ///
1804        /// ```rust,no_run
1805        /// # #[cfg(all(feature = "async", feature = "tokio"))]
1806        /// # {
1807        /// use cel_cxx::*;
1808        ///
1809        /// let env = Env::builder()
1810        ///     .build()?
1811        ///     .use_tokio();
1812        /// # }
1813        /// # Ok::<(), cel_cxx::Error>(())
1814        /// ```
1815        #[cfg(feature = "tokio")]
1816        #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
1817        pub fn use_tokio(self) -> Env<'f, Fm, Tokio> {
1818            self.use_runtime::<Tokio>()
1819        }
1820
1821        /// Configures the environment to use the async-std runtime.
1822        ///
1823        /// This is a convenience method for setting the runtime to async-std.
1824        /// Requires the `async-std` feature to be enabled.
1825        ///
1826        /// # Examples
1827        ///
1828        /// ```rust,no_run
1829        /// # #[cfg(all(feature = "async", feature = "async-std"))]
1830        /// # {
1831        /// use cel_cxx::*;
1832        ///
1833        /// let env = Env::builder()
1834        ///     .build()?
1835        ///     .use_async_std();
1836        /// # }
1837        /// # Ok::<(), cel_cxx::Error>(())
1838        /// ```
1839        #[cfg(feature = "async-std")]
1840        #[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
1841        pub fn use_async_std(self) -> Env<'f, Fm, AsyncStd> {
1842            self.use_runtime::<AsyncStd>()
1843        }
1844
1845        /// Configures the environment to use the smol runtime.
1846        ///
1847        /// This is a convenience method for setting the runtime to smol.
1848        /// Requires the `smol` feature to be enabled.
1849        ///
1850        /// # Examples
1851        ///
1852        /// ```rust,no_run
1853        /// # #[cfg(feature = "async")]
1854        /// # {
1855        /// use cel_cxx::*;
1856        ///
1857        /// let env = Env::builder().use_smol();
1858        /// # }
1859        /// # Ok::<(), cel_cxx::Error>(())
1860        /// ```
1861        #[cfg(feature = "smol")]
1862        #[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
1863        pub fn use_smol(self) -> Env<'f, Fm, Smol> {
1864            self.use_runtime::<Smol>()
1865        }
1866    }
1867
1868    impl<'f, Fm: FnMarker> EnvBuilder<'f, Fm, ()> {
1869        /// Sets the async runtime for the environment builder.
1870        ///
1871        /// This method specifies which async runtime should be used by
1872        /// environments built from this builder.
1873        ///
1874        /// # Type Parameters
1875        ///
1876        /// * `Rt` - The runtime type to use (must implement [`Runtime`])
1877        ///
1878        /// # Examples
1879        ///
1880        /// ```rust,no_run
1881        /// # #[cfg(feature = "async")]
1882        /// # {
1883        /// use cel_cxx::*;
1884        ///
1885        /// let builder = Env::builder().use_runtime::<Tokio>();
1886        /// # }
1887        /// ```
1888        pub fn use_runtime<Rt: Runtime>(self) -> EnvBuilder<'f, Fm, Rt> {
1889            EnvBuilder {
1890                macros: self.macros,
1891                function_registry: self.function_registry,
1892                variable_registry: self.variable_registry,
1893                options: self.options,
1894                _fn_marker: self._fn_marker,
1895                _rt_marker: std::marker::PhantomData,
1896            }
1897        }
1898
1899        /// Configures the builder to use the Tokio async runtime.
1900        ///
1901        /// This is a convenience method for setting the runtime to Tokio.
1902        /// Requires the `tokio` feature to be enabled.
1903        ///
1904        /// # Examples
1905        ///
1906        /// ```rust,no_run
1907        /// # #[cfg(all(feature = "async", feature = "tokio"))]
1908        /// # {
1909        /// use cel_cxx::*;
1910        ///
1911        /// let builder = Env::builder().use_tokio();
1912        /// # }
1913        /// ```
1914        #[cfg(feature = "tokio")]
1915        #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
1916        pub fn use_tokio(self) -> EnvBuilder<'f, Fm, Tokio> {
1917            self.use_runtime::<Tokio>()
1918        }
1919
1920        /// Configures the builder to use the async-std runtime.
1921        ///
1922        /// This is a convenience method for setting the runtime to async-std.
1923        /// Requires the `async-std` feature to be enabled.
1924        ///
1925        /// # Examples
1926        ///
1927        /// ```rust,no_run
1928        /// # #[cfg(all(feature = "async", feature = "async-std"))]
1929        /// # {
1930        /// use cel_cxx::*;
1931        ///
1932        /// let builder = Env::builder().use_async_std();
1933        /// # }
1934        /// ```
1935        #[cfg(feature = "async-std")]
1936        #[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
1937        pub fn use_async_std(self) -> EnvBuilder<'f, Fm, AsyncStd> {
1938            self.use_runtime::<AsyncStd>()
1939        }
1940
1941        /// Configures the builder to use the smol runtime.
1942        ///
1943        /// This is a convenience method for setting the runtime to smol.
1944        /// Requires the `smol` feature to be enabled.
1945        ///
1946        /// # Examples
1947        ///
1948        /// ```rust,no_run
1949        /// # #[cfg(feature = "async")]
1950        /// # {
1951        /// use cel_cxx::*;
1952        ///
1953        /// let builder = Env::builder().use_smol();
1954        /// # }
1955        /// ```
1956        #[cfg(feature = "smol")]
1957        #[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
1958        pub fn use_smol(self) -> EnvBuilder<'f, Fm, Smol> {
1959            self.use_runtime::<Smol>()
1960        }
1961    }
1962};
1963
1964impl<'f, Fm: FnMarker, Rm: RuntimeMarker> std::fmt::Debug for Env<'f, Fm, Rm> {
1965    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1966        f.debug_struct("Env").field("inner", &self.inner).finish()
1967    }
1968}
1969
1970impl<'f, Fm: FnMarker, Rm: RuntimeMarker> Clone for Env<'f, Fm, Rm> {
1971    fn clone(&self) -> Self {
1972        Env {
1973            inner: self.inner.clone(),
1974            _fn_marker: self._fn_marker,
1975            _rt_marker: self._rt_marker,
1976        }
1977    }
1978}
1979
1980impl<'f, Fm: FnMarker, Rm: RuntimeMarker> std::fmt::Debug for EnvBuilder<'f, Fm, Rm> {
1981    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1982        f.debug_struct("EnvBuilder")
1983            .field("function_registry", &self.function_registry)
1984            .field("variable_registry", &self.variable_registry)
1985            .finish()
1986    }
1987}
1988
1989impl<'f, Fm: FnMarker, Rm: RuntimeMarker> Default for EnvBuilder<'f, Fm, Rm> {
1990    fn default() -> Self {
1991        EnvBuilder {
1992            macros: HashSet::new(),
1993            function_registry: FunctionRegistry::new(),
1994            variable_registry: VariableRegistry::new(),
1995            options: EnvInnerOptions::default(),
1996            _fn_marker: std::marker::PhantomData,
1997            _rt_marker: std::marker::PhantomData,
1998        }
1999    }
2000}