cel_cxx/env/
mod.rs

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