cel_cxx_ffi/
runtime.rs

1use std::pin::Pin;
2
3use crate::absl::{Span, Status, StringView};
4use crate::common::{Ast, Kind, OpaqueType, Value};
5use crate::protobuf::{Arena, DescriptorPool, MessageFactory};
6
7#[cxx::bridge]
8mod ffi {
9    #[namespace = "absl"]
10    unsafe extern "C++" {
11        include!(<absl/status/status.h>);
12        type Status = super::Status;
13        include!(<absl/strings/string_view.h>);
14        type string_view<'a> = super::StringView<'a>;
15    }
16
17    #[namespace = "google::protobuf"]
18    unsafe extern "C++" {
19        include!(<google/protobuf/descriptor.h>);
20        type Arena = super::Arena;
21        type MessageFactory = super::MessageFactory;
22        type DescriptorPool = super::DescriptorPool;
23    }
24
25    #[namespace = "cel"]
26    unsafe extern "C++" {
27        include!(<runtime/runtime.h>);
28        include!(<runtime/function.h>);
29        include!(<runtime/standard_functions.h>);
30        include!(<common/ast.h>);
31
32        type Kind = super::Kind;
33        type Value<'a> = super::Value<'a>;
34        type OpaqueType<'a> = super::OpaqueType<'a>;
35        type Ast = super::Ast;
36
37        type UnknownProcessingOptions = super::UnknownProcessingOptions;
38        #[rust_name = "Activation"]
39        type ActivationInterface<'f>;
40        type Runtime<'a, 'f>;
41        type RuntimeBuilder<'a, 'f>;
42        fn type_registry<'this, 'a, 'f>(
43            self: Pin<&'this mut RuntimeBuilder<'a, 'f>>,
44        ) -> Pin<&'this mut TypeRegistry<'this, 'a>>;
45        fn function_registry<'this, 'a, 'f>(
46            self: Pin<&'this mut RuntimeBuilder<'a, 'f>>,
47        ) -> Pin<&'this mut FunctionRegistry<'f>>;
48
49        type RuntimeOptions;
50
51        type Function<'a>;
52        type FunctionDescriptor;
53        fn name(self: &FunctionDescriptor) -> &CxxString;
54        fn receiver_style(self: &FunctionDescriptor) -> bool;
55        fn types(self: &FunctionDescriptor) -> &CxxVector<Kind>;
56        fn is_strict(self: &FunctionDescriptor) -> bool;
57        #[rust_name = "shape_matches"]
58        fn ShapeMatches(self: &FunctionDescriptor, other: &FunctionDescriptor) -> bool;
59
60        type FunctionOverloadReference<'a, 'f> = super::FunctionOverloadReference<'a, 'f>;
61
62        type FunctionRegistry<'f>;
63        #[rust_name = "register"]
64        fn Register<'f>(
65            self: Pin<&mut FunctionRegistry<'f>>,
66            descriptor: &FunctionDescriptor,
67            function: UniquePtr<Function<'f>>,
68        ) -> Status;
69        #[rust_name = "register_lazy"]
70        fn RegisterLazyFunction<'f>(
71            self: Pin<&mut FunctionRegistry<'f>>,
72            descriptor: &FunctionDescriptor,
73        ) -> Status;
74
75        fn RegisterStandardFunctions(
76            function_registry: Pin<&mut FunctionRegistry>,
77            options: &RuntimeOptions,
78        ) -> Status;
79
80        type Program<'a, 'f>;
81        type TypeRegistry<'d, 'a>;
82        #[rust_name = "register_type"]
83        fn RegisterType<'d, 'a>(
84            self: Pin<&mut TypeRegistry<'d, 'a>>,
85            opaque_type: &OpaqueType<'a>,
86        ) -> Status;
87    }
88
89    // We use our patched version of EnableOptionalTypes
90    //
91    //#[namespace = "cel::extensions"]
92    //unsafe extern "C++" {
93    //    include!(<runtime/optional_types.h>);
94    //    fn EnableOptionalTypes(runtime_builder: Pin<&mut RuntimeBuilder>) -> Status;
95    //}
96
97    #[namespace = "cel::runtime_internal"]
98    unsafe extern "C++" {
99        include!(<runtime/function_provider.h>);
100        type FunctionProvider;
101    }
102
103    #[namespace = "rust::cel_cxx"]
104    unsafe extern "C++" {
105        include!(<cel-cxx-ffi/include/runtime.h>);
106        type LazyOverload<'a> = super::LazyOverload<'a>;
107
108        type Span_Value<'a, 'v> = super::Span<'a, super::Value<'v>>;
109        type Span_CxxString<'a> = super::Span<'a, cxx::CxxString>;
110        type Span_Kind<'a> = super::Span<'a, super::Kind>;
111
112        type FunctionRegistryIterator<'a> = super::FunctionRegistryIterator<'a>;
113        fn FunctionRegistryIterator_next<'a>(
114            iter: &mut FunctionRegistryIterator<'a>,
115            key: &mut UniquePtr<CxxString>,
116            value: &mut UniquePtr<CxxVector<FunctionDescriptor>>,
117        ) -> bool;
118        fn FunctionRegistryIterator_drop<'a>(iter: &mut FunctionRegistryIterator<'a>);
119
120        // Activation
121        fn Activation_new<'f>(ffi: Box<AnyFfiActivation<'f>>) -> UniquePtr<Activation<'f>>;
122
123        // FunctionRegistry
124        fn FunctionRegistry_find_static_overloads<'this, 'f>(
125            function_registry: &'this FunctionRegistry<'f>,
126            name: string_view<'_>,
127            receiver_style: bool,
128            types: Span_Kind<'_>,
129        ) -> Vec<FunctionOverloadReference<'this, 'f>>;
130        fn FunctionRegistry_find_static_overloads_by_arity<'this, 'f>(
131            function_registry: &'this FunctionRegistry<'f>,
132            name: string_view<'_>,
133            receiver_style: bool,
134            arity: usize,
135        ) -> Vec<FunctionOverloadReference<'this, 'f>>;
136        fn FunctionRegistry_find_lazy_overloads<'this, 'f>(
137            function_registry: &'this FunctionRegistry<'f>,
138            name: string_view<'_>,
139            receiver_style: bool,
140            types: Span_Kind<'_>,
141        ) -> Vec<LazyOverload<'this>>;
142        fn FunctionRegistry_find_lazy_overloads_by_arity<'this, 'f>(
143            function_registry: &'this FunctionRegistry<'f>,
144            name: string_view<'_>,
145            receiver_style: bool,
146            arity: usize,
147        ) -> Vec<LazyOverload<'this>>;
148        fn FunctionRegistry_list_functions<'this, 'f>(
149            function_registry: &'this FunctionRegistry<'f>,
150        ) -> FunctionRegistryIterator<'this>;
151
152        // Runtime
153        fn Runtime_create_program<'a, 'f>(
154            runtime: &Runtime<'a, 'f>,
155            ast: UniquePtr<Ast>,
156            result: &mut UniquePtr<Program<'a, 'f>>,
157        ) -> Status;
158
159        // RuntimeBuilder
160        fn RuntimeBuilder_new<'this, 'a, 'f>(
161            descriptor_pool: SharedPtr<DescriptorPool>,
162            options: &RuntimeOptions,
163            result: &'this mut UniquePtr<RuntimeBuilder<'a, 'f>>,
164        ) -> Status;
165        fn RuntimeBuilder_options<'this, 'a, 'f>(
166            runtime_builder: &'this RuntimeBuilder<'a, 'f>,
167        ) -> &'this RuntimeOptions;
168        fn RuntimeBuilder_build<'a, 'f>(
169            runtime_builder: Pin<&mut RuntimeBuilder<'a, 'f>>,
170            result: &mut UniquePtr<Runtime<'a, 'f>>,
171        ) -> Status;
172
173        // RuntimeOptions
174        fn RuntimeOptions_new() -> UniquePtr<RuntimeOptions>;
175
176        // RuntimeOptions getters and setters
177        fn RuntimeOptions_container(runtime_options: &RuntimeOptions) -> &str;
178        fn RuntimeOptions_container_mut(
179            runtime_options: Pin<&mut RuntimeOptions>,
180        ) -> Pin<&mut CxxString>;
181        fn RuntimeOptions_unknown_processing(
182            runtime_options: &RuntimeOptions,
183        ) -> UnknownProcessingOptions;
184        fn RuntimeOptions_unknown_processing_mut(
185            runtime_options: Pin<&mut RuntimeOptions>,
186        ) -> &mut UnknownProcessingOptions;
187        fn RuntimeOptions_enable_missing_attribute_errors(runtime_options: &RuntimeOptions)
188            -> bool;
189        fn RuntimeOptions_enable_missing_attribute_errors_mut(
190            runtime_options: Pin<&mut RuntimeOptions>,
191        ) -> &mut bool;
192        fn RuntimeOptions_enable_timestamp_duration_overflow_errors(
193            runtime_options: &RuntimeOptions,
194        ) -> bool;
195        fn RuntimeOptions_enable_timestamp_duration_overflow_errors_mut(
196            runtime_options: Pin<&mut RuntimeOptions>,
197        ) -> &mut bool;
198        fn RuntimeOptions_short_circuiting(runtime_options: &RuntimeOptions) -> bool;
199        fn RuntimeOptions_short_circuiting_mut(
200            runtime_options: Pin<&mut RuntimeOptions>,
201        ) -> &mut bool;
202        fn RuntimeOptions_enable_comprehension(runtime_options: &RuntimeOptions) -> bool;
203        fn RuntimeOptions_enable_comprehension_mut(
204            runtime_options: Pin<&mut RuntimeOptions>,
205        ) -> &mut bool;
206        fn RuntimeOptions_comprehension_max_iterations(runtime_options: &RuntimeOptions) -> i32;
207        fn RuntimeOptions_comprehension_max_iterations_mut(
208            runtime_options: Pin<&mut RuntimeOptions>,
209        ) -> &mut i32;
210        fn RuntimeOptions_enable_comprehension_list_append(
211            runtime_options: &RuntimeOptions,
212        ) -> bool;
213        fn RuntimeOptions_enable_comprehension_list_append_mut(
214            runtime_options: Pin<&mut RuntimeOptions>,
215        ) -> &mut bool;
216        fn RuntimeOptions_enable_regex(runtime_options: &RuntimeOptions) -> bool;
217        fn RuntimeOptions_enable_regex_mut(runtime_options: Pin<&mut RuntimeOptions>) -> &mut bool;
218        fn RuntimeOptions_regex_max_program_size(runtime_options: &RuntimeOptions) -> i32;
219        fn RuntimeOptions_regex_max_program_size_mut(
220            runtime_options: Pin<&mut RuntimeOptions>,
221        ) -> &mut i32;
222        fn RuntimeOptions_enable_string_conversion(runtime_options: &RuntimeOptions) -> bool;
223        fn RuntimeOptions_enable_string_conversion_mut(
224            runtime_options: Pin<&mut RuntimeOptions>,
225        ) -> &mut bool;
226        fn RuntimeOptions_enable_string_concat(runtime_options: &RuntimeOptions) -> bool;
227        fn RuntimeOptions_enable_string_concat_mut(
228            runtime_options: Pin<&mut RuntimeOptions>,
229        ) -> &mut bool;
230        fn RuntimeOptions_enable_list_concat(runtime_options: &RuntimeOptions) -> bool;
231        fn RuntimeOptions_enable_list_concat_mut(
232            runtime_options: Pin<&mut RuntimeOptions>,
233        ) -> &mut bool;
234        fn RuntimeOptions_enable_list_contains(runtime_options: &RuntimeOptions) -> bool;
235        fn RuntimeOptions_enable_list_contains_mut(
236            runtime_options: Pin<&mut RuntimeOptions>,
237        ) -> &mut bool;
238        fn RuntimeOptions_fail_on_warnings(runtime_options: &RuntimeOptions) -> bool;
239        fn RuntimeOptions_fail_on_warnings_mut(
240            runtime_options: Pin<&mut RuntimeOptions>,
241        ) -> &mut bool;
242        fn RuntimeOptions_enable_qualified_type_identifiers(
243            runtime_options: &RuntimeOptions,
244        ) -> bool;
245        fn RuntimeOptions_enable_qualified_type_identifiers_mut(
246            runtime_options: Pin<&mut RuntimeOptions>,
247        ) -> &mut bool;
248        fn RuntimeOptions_enable_heterogeneous_equality(runtime_options: &RuntimeOptions) -> bool;
249        fn RuntimeOptions_enable_heterogeneous_equality_mut(
250            runtime_options: Pin<&mut RuntimeOptions>,
251        ) -> &mut bool;
252        fn RuntimeOptions_enable_empty_wrapper_null_unboxing(
253            runtime_options: &RuntimeOptions,
254        ) -> bool;
255        fn RuntimeOptions_enable_empty_wrapper_null_unboxing_mut(
256            runtime_options: Pin<&mut RuntimeOptions>,
257        ) -> &mut bool;
258        fn RuntimeOptions_enable_lazy_bind_initialization(runtime_options: &RuntimeOptions)
259            -> bool;
260        fn RuntimeOptions_enable_lazy_bind_initialization_mut(
261            runtime_options: Pin<&mut RuntimeOptions>,
262        ) -> &mut bool;
263        fn RuntimeOptions_max_recursion_depth(runtime_options: &RuntimeOptions) -> i32;
264        fn RuntimeOptions_max_recursion_depth_mut(
265            runtime_options: Pin<&mut RuntimeOptions>,
266        ) -> &mut i32;
267        fn RuntimeOptions_enable_recursive_tracing(runtime_options: &RuntimeOptions) -> bool;
268        fn RuntimeOptions_enable_recursive_tracing_mut(
269            runtime_options: Pin<&mut RuntimeOptions>,
270        ) -> &mut bool;
271        fn RuntimeOptions_enable_fast_builtins(runtime_options: &RuntimeOptions) -> bool;
272        fn RuntimeOptions_enable_fast_builtins_mut(
273            runtime_options: Pin<&mut RuntimeOptions>,
274        ) -> &mut bool;
275
276        // FunctionDescriptor
277        fn FunctionDescriptor_new(
278            name: &str,
279            receiver_style: bool,
280            types: &[Kind],
281            is_strict: bool,
282        ) -> UniquePtr<FunctionDescriptor>;
283
284        fn FunctionDescriptor_new_shared(
285            name: &str,
286            receiver_style: bool,
287            types: &[Kind],
288            is_strict: bool,
289        ) -> SharedPtr<FunctionDescriptor>;
290
291        // Program
292        fn Program_evaluate<'a, 'f, 'a2, 'f2>(
293            program: &Program<'a, 'f>,
294            arena: &'a2 Arena,
295            message_factory: &MessageFactory,
296            activation: &Activation<'f2>,
297            result: &mut UniquePtr<Value<'a2>>,
298        ) -> Status;
299        fn Program_evaluate2<'a, 'f, 'a2, 'f2>(
300            program: &Program<'a, 'f>,
301            arena: &'a2 Arena,
302            activation: &Activation<'f2>,
303            result: &mut UniquePtr<Value<'a2>>,
304        ) -> Status;
305
306        // Function
307        fn Function_new<'a>(ffi_function: Box<AnyFfiFunction<'a>>) -> UniquePtr<Function<'a>>;
308
309        include!(<cel-cxx-ffi/include/optional.h>);
310        fn EnableOptionalTypes(runtime_builder: Pin<&mut RuntimeBuilder>) -> Status;
311    }
312    #[namespace = "rust::cel_cxx"]
313    extern "Rust" {
314        type AnyFfiActivation<'f>;
315        #[cxx_name = "FindVariable"]
316        unsafe fn find_variable<'f, 'a>(
317            self: &AnyFfiActivation<'f>,
318            name: &str,
319            descriptor_pool: &'a DescriptorPool,
320            message_factory: &'a MessageFactory,
321            arena: &'a Arena,
322            result: &mut UniquePtr<Value<'a>>,
323        ) -> Status;
324        #[cxx_name = "FindFunctionOverloads"]
325        unsafe fn find_function_overloads<'this, 'f>(
326            self: &'this AnyFfiActivation<'f>,
327            name: &str,
328        ) -> Vec<FunctionOverloadReference<'this, 'f>>;
329
330        type AnyFfiFunction<'f>;
331        #[cxx_name = "Invoke"]
332        unsafe fn invoke<'f, 'a>(
333            self: &AnyFfiFunction<'f>,
334            args: Span_Value<'_, 'a>,
335            descriptor_pool: &'a DescriptorPool,
336            message_factory: &'a MessageFactory,
337            arena: &'a Arena,
338            overload_id: Span_CxxString<'_>,
339            result: Pin<&mut Value<'a>>,
340        ) -> Status;
341    }
342
343    impl<'a, 'f> Vec<FunctionOverloadReference<'a, 'f>> {}
344    impl<'a> Vec<LazyOverload<'a>> {}
345}
346
347// Activation
348pub use ffi::Activation;
349unsafe impl<'f> Send for Activation<'f> {}
350unsafe impl<'f> Sync for Activation<'f> {}
351
352impl<'f> Activation<'f> {
353    pub fn new<T: FfiActivation<'f> + 'f>(ffi: T) -> cxx::UniquePtr<Self> {
354        ffi::Activation_new(Box::new(AnyFfiActivation::new(ffi)))
355    }
356}
357
358// FunctionOverloadReference
359#[repr(C)]
360#[derive(Clone, Copy)]
361pub struct FunctionOverloadReference<'a, 'f> {
362    descriptor: &'a FunctionDescriptor,
363    implementation: &'a Function<'f>,
364}
365
366unsafe impl<'a, 'f> cxx::ExternType for FunctionOverloadReference<'a, 'f> {
367    type Id = cxx::type_id!("cel::FunctionOverloadReference");
368    type Kind = cxx::kind::Trivial;
369}
370
371impl<'a, 'f> FunctionOverloadReference<'a, 'f> {
372    pub fn new(descriptor: &'a FunctionDescriptor, implementation: &'a Function<'f>) -> Self {
373        Self {
374            descriptor,
375            implementation,
376        }
377    }
378
379    pub fn descriptor(&self) -> &'a FunctionDescriptor {
380        self.descriptor
381    }
382
383    pub fn implementation(&self) -> &'a Function<'f> {
384        self.implementation
385    }
386}
387
388// FunctionProvider
389pub use ffi::FunctionProvider;
390unsafe impl Send for FunctionProvider {}
391unsafe impl Sync for FunctionProvider {}
392
393// LazyOverload
394#[repr(C)]
395#[derive(Clone, Copy)]
396pub struct LazyOverload<'a> {
397    descriptor: &'a FunctionDescriptor,
398    function_provider: &'a FunctionProvider,
399}
400
401unsafe impl<'a> cxx::ExternType for LazyOverload<'a> {
402    type Id = cxx::type_id!("rust::cel_cxx::LazyOverload");
403    type Kind = cxx::kind::Trivial;
404}
405
406impl<'a> LazyOverload<'a> {
407    pub fn new(
408        descriptor: &'a FunctionDescriptor,
409        function_provider: &'a FunctionProvider,
410    ) -> Self {
411        Self {
412            descriptor,
413            function_provider,
414        }
415    }
416
417    pub fn descriptor(&self) -> &'a FunctionDescriptor {
418        self.descriptor
419    }
420
421    pub fn function_provider(&self) -> &'a FunctionProvider {
422        self.function_provider
423    }
424}
425
426// FfiActivation
427pub trait FfiActivation<'f> {
428    fn find_variable<'a>(
429        &self,
430        name: &str,
431        descriptor_pool: &'a DescriptorPool,
432        message_factory: &'a MessageFactory,
433        arena: &'a Arena,
434    ) -> Result<Option<cxx::UniquePtr<Value<'a>>>, Status>;
435
436    fn find_function_overloads<'this>(
437        &'this self,
438        name: &str,
439    ) -> Vec<FunctionOverloadReference<'this, 'f>>;
440}
441
442// AnyFfiActivation
443struct AnyFfiActivation<'f>(Box<dyn FfiActivation<'f> + 'f>);
444
445impl<'f> AnyFfiActivation<'f> {
446    fn new<T: FfiActivation<'f> + 'f>(activation: T) -> Self {
447        Self(Box::new(activation))
448    }
449
450    fn find_variable<'a>(
451        &self,
452        name: &str,
453        descriptor_pool: &'a DescriptorPool,
454        message_factory: &'a MessageFactory,
455        arena: &'a Arena,
456        result: &mut cxx::UniquePtr<Value<'a>>,
457    ) -> Status {
458        *result = cxx::UniquePtr::null();
459
460        match self
461            .0
462            .find_variable(name, descriptor_pool, message_factory, arena)
463        {
464            Ok(Some(value)) => {
465                *result = value;
466                Status::ok()
467            }
468            Ok(None) => Status::ok(),
469            Err(status) => status,
470        }
471    }
472
473    fn find_function_overloads<'this>(
474        &'this self,
475        name: &str,
476    ) -> Vec<FunctionOverloadReference<'this, 'f>> {
477        self.0.find_function_overloads(name)
478    }
479}
480
481// Runtime
482pub use ffi::Runtime;
483unsafe impl<'a, 'f> Send for Runtime<'a, 'f> {}
484unsafe impl<'a, 'f> Sync for Runtime<'a, 'f> {}
485
486impl<'a, 'f> Runtime<'a, 'f> {
487    pub fn create_program(
488        &self,
489        ast: cxx::UniquePtr<Ast>,
490    ) -> Result<cxx::UniquePtr<Program<'a, 'f>>, Status> {
491        let mut result = cxx::UniquePtr::null();
492        let status = ffi::Runtime_create_program(self, ast, &mut result);
493        if status.is_ok() {
494            Ok(result)
495        } else {
496            Err(status)
497        }
498    }
499}
500
501impl<'a, 'f> std::fmt::Debug for Runtime<'a, 'f> {
502    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
503        let ptr = self as *const Runtime<'a, 'f>;
504        write!(f, "Runtime {{ ptr: {ptr:p} }}")
505    }
506}
507
508// RuntimeBuilder
509pub use ffi::RuntimeBuilder;
510unsafe impl<'a, 'f> Send for RuntimeBuilder<'a, 'f> {}
511unsafe impl<'a, 'f> Sync for RuntimeBuilder<'a, 'f> {}
512
513impl<'a, 'f> RuntimeBuilder<'a, 'f> {
514    pub fn new(
515        descriptor_pool: cxx::SharedPtr<DescriptorPool>,
516        options: &RuntimeOptions,
517    ) -> Result<cxx::UniquePtr<Self>, Status> {
518        let mut result = cxx::UniquePtr::null();
519        let status = ffi::RuntimeBuilder_new(descriptor_pool, options, &mut result);
520        if status.is_ok() {
521            Ok(result)
522        } else {
523            Err(status)
524        }
525    }
526
527    pub fn enable_standard(self: Pin<&mut Self>, options: &RuntimeOptions) -> Result<(), Status> {
528        let status = ffi::RegisterStandardFunctions(self.function_registry(), options);
529        if status.is_ok() {
530            Ok(())
531        } else {
532            Err(status)
533        }
534    }
535
536    #[allow(unused_variables)]
537    pub fn enable_optional(self: Pin<&mut Self>, options: &RuntimeOptions) -> Result<(), Status> {
538        let status = ffi::EnableOptionalTypes(self);
539        if status.is_ok() {
540            Ok(())
541        } else {
542            Err(status)
543        }
544    }
545
546    pub fn options(&self) -> &RuntimeOptions {
547        ffi::RuntimeBuilder_options(self)
548    }
549
550    pub fn build(self: Pin<&mut Self>) -> Result<cxx::UniquePtr<Runtime<'a, 'f>>, Status> {
551        let mut result = cxx::UniquePtr::null();
552        let status = ffi::RuntimeBuilder_build(self, &mut result);
553        if status.is_ok() {
554            Ok(result)
555        } else {
556            Err(status)
557        }
558    }
559}
560
561impl<'a, 'f> std::fmt::Debug for RuntimeBuilder<'a, 'f> {
562    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
563        let ptr = self as *const RuntimeBuilder<'a, 'f>;
564        write!(f, "RuntimeBuilder {{ ptr: {ptr:p} }}")
565    }
566}
567
568// RuntimeOptions
569#[repr(i32)]
570#[derive(Clone, Copy, PartialEq, Eq, Default)]
571pub enum UnknownProcessingOptions {
572    #[default]
573    /// No unknown processing.
574    Disabled,
575    /// Only attributes supported.
576    AttributeOnly,
577    /// Attributes and functions supported. Function results are dependent on the
578    /// logic for handling unknown_attributes, so clients must opt in to both.
579    AttributeAndFunction,
580}
581
582unsafe impl cxx::ExternType for UnknownProcessingOptions {
583    type Id = cxx::type_id!("cel::UnknownProcessingOptions");
584    type Kind = cxx::kind::Trivial;
585}
586
587pub use ffi::RuntimeOptions;
588unsafe impl Send for RuntimeOptions {}
589unsafe impl Sync for RuntimeOptions {}
590
591impl RuntimeOptions {
592    pub fn new() -> cxx::UniquePtr<Self> {
593        ffi::RuntimeOptions_new()
594    }
595
596    pub fn container(&self) -> &str {
597        ffi::RuntimeOptions_container(self)
598    }
599
600    pub fn container_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut cxx::CxxString> {
601        ffi::RuntimeOptions_container_mut(self)
602    }
603
604    pub fn unknown_processing(&self) -> UnknownProcessingOptions {
605        ffi::RuntimeOptions_unknown_processing(self)
606    }
607
608    pub fn unknown_processing_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut UnknownProcessingOptions {
609        ffi::RuntimeOptions_unknown_processing_mut(self)
610    }
611
612    pub fn enable_missing_attribute_errors(&self) -> bool {
613        ffi::RuntimeOptions_enable_missing_attribute_errors(self)
614    }
615
616    pub fn enable_missing_attribute_errors_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
617        ffi::RuntimeOptions_enable_missing_attribute_errors_mut(self)
618    }
619
620    pub fn enable_timestamp_duration_overflow_errors(&self) -> bool {
621        ffi::RuntimeOptions_enable_timestamp_duration_overflow_errors(self)
622    }
623
624    pub fn enable_timestamp_duration_overflow_errors_mut<'a>(
625        self: Pin<&'a mut Self>,
626    ) -> &'a mut bool {
627        ffi::RuntimeOptions_enable_timestamp_duration_overflow_errors_mut(self)
628    }
629
630    pub fn short_circuiting(&self) -> bool {
631        ffi::RuntimeOptions_short_circuiting(self)
632    }
633
634    pub fn short_circuiting_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
635        ffi::RuntimeOptions_short_circuiting_mut(self)
636    }
637
638    pub fn enable_comprehension(&self) -> bool {
639        ffi::RuntimeOptions_enable_comprehension(self)
640    }
641
642    pub fn enable_comprehension_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
643        ffi::RuntimeOptions_enable_comprehension_mut(self)
644    }
645
646    pub fn comprehension_max_iterations(&self) -> i32 {
647        ffi::RuntimeOptions_comprehension_max_iterations(self)
648    }
649
650    pub fn comprehension_max_iterations_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
651        ffi::RuntimeOptions_comprehension_max_iterations_mut(self)
652    }
653
654    pub fn enable_comprehension_list_append(&self) -> bool {
655        ffi::RuntimeOptions_enable_comprehension_list_append(self)
656    }
657
658    pub fn enable_comprehension_list_append_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
659        ffi::RuntimeOptions_enable_comprehension_list_append_mut(self)
660    }
661
662    pub fn enable_regex(&self) -> bool {
663        ffi::RuntimeOptions_enable_regex(self)
664    }
665
666    pub fn enable_regex_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
667        ffi::RuntimeOptions_enable_regex_mut(self)
668    }
669
670    pub fn regex_max_program_size(&self) -> i32 {
671        ffi::RuntimeOptions_regex_max_program_size(self)
672    }
673
674    pub fn regex_max_program_size_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
675        ffi::RuntimeOptions_regex_max_program_size_mut(self)
676    }
677
678    pub fn enable_string_conversion(&self) -> bool {
679        ffi::RuntimeOptions_enable_string_conversion(self)
680    }
681
682    pub fn enable_string_conversion_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
683        ffi::RuntimeOptions_enable_string_conversion_mut(self)
684    }
685
686    pub fn enable_string_concat(&self) -> bool {
687        ffi::RuntimeOptions_enable_string_concat(self)
688    }
689
690    pub fn enable_string_concat_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
691        ffi::RuntimeOptions_enable_string_concat_mut(self)
692    }
693
694    pub fn enable_list_concat(&self) -> bool {
695        ffi::RuntimeOptions_enable_list_concat(self)
696    }
697
698    pub fn enable_list_concat_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
699        ffi::RuntimeOptions_enable_list_concat_mut(self)
700    }
701
702    pub fn enable_list_contains(&self) -> bool {
703        ffi::RuntimeOptions_enable_list_contains(self)
704    }
705
706    pub fn enable_list_contains_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
707        ffi::RuntimeOptions_enable_list_contains_mut(self)
708    }
709
710    pub fn fail_on_warnings(&self) -> bool {
711        ffi::RuntimeOptions_fail_on_warnings(self)
712    }
713
714    pub fn fail_on_warnings_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
715        ffi::RuntimeOptions_fail_on_warnings_mut(self)
716    }
717
718    pub fn enable_qualified_type_identifiers(&self) -> bool {
719        ffi::RuntimeOptions_enable_qualified_type_identifiers(self)
720    }
721
722    pub fn enable_qualified_type_identifiers_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
723        ffi::RuntimeOptions_enable_qualified_type_identifiers_mut(self)
724    }
725
726    pub fn enable_heterogeneous_equality(&self) -> bool {
727        ffi::RuntimeOptions_enable_heterogeneous_equality(self)
728    }
729
730    pub fn enable_heterogeneous_equality_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
731        ffi::RuntimeOptions_enable_heterogeneous_equality_mut(self)
732    }
733
734    pub fn enable_empty_wrapper_null_unboxing(&self) -> bool {
735        ffi::RuntimeOptions_enable_empty_wrapper_null_unboxing(self)
736    }
737
738    pub fn enable_empty_wrapper_null_unboxing_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
739        ffi::RuntimeOptions_enable_empty_wrapper_null_unboxing_mut(self)
740    }
741
742    pub fn enable_lazy_bind_initialization(&self) -> bool {
743        ffi::RuntimeOptions_enable_lazy_bind_initialization(self)
744    }
745
746    pub fn enable_lazy_bind_initialization_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
747        ffi::RuntimeOptions_enable_lazy_bind_initialization_mut(self)
748    }
749
750    pub fn max_recursion_depth(&self) -> i32 {
751        ffi::RuntimeOptions_max_recursion_depth(self)
752    }
753
754    pub fn max_recursion_depth_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
755        ffi::RuntimeOptions_max_recursion_depth_mut(self)
756    }
757
758    pub fn enable_recursive_tracing(&self) -> bool {
759        ffi::RuntimeOptions_enable_recursive_tracing(self)
760    }
761
762    pub fn enable_recursive_tracing_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
763        ffi::RuntimeOptions_enable_recursive_tracing_mut(self)
764    }
765
766    pub fn enable_fast_builtins(&self) -> bool {
767        ffi::RuntimeOptions_enable_fast_builtins(self)
768    }
769
770    pub fn enable_fast_builtins_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
771        ffi::RuntimeOptions_enable_fast_builtins_mut(self)
772    }
773}
774
775// FunctionDescriptor
776pub use ffi::FunctionDescriptor;
777unsafe impl Send for FunctionDescriptor {}
778unsafe impl Sync for FunctionDescriptor {}
779
780impl FunctionDescriptor {
781    pub fn new(
782        name: &str,
783        receiver_style: bool,
784        types: &[Kind],
785        is_strict: bool,
786    ) -> cxx::UniquePtr<Self> {
787        ffi::FunctionDescriptor_new(name, receiver_style, types, is_strict)
788    }
789
790    pub fn new_shared(
791        name: &str,
792        receiver_style: bool,
793        types: &[Kind],
794        is_strict: bool,
795    ) -> cxx::SharedPtr<Self> {
796        ffi::FunctionDescriptor_new_shared(name, receiver_style, types, is_strict)
797    }
798}
799
800// FunctionRegistry
801pub use ffi::FunctionRegistry;
802unsafe impl<'f> Send for FunctionRegistry<'f> {}
803unsafe impl<'f> Sync for FunctionRegistry<'f> {}
804
805impl<'f> FunctionRegistry<'f> {
806    pub fn find_static_overloads<'this>(
807        &'this self,
808        name: StringView<'_>,
809        receiver_style: bool,
810        types: Span<'_, Kind>,
811    ) -> Vec<FunctionOverloadReference<'this, 'f>> {
812        ffi::FunctionRegistry_find_static_overloads(self, name, receiver_style, types)
813    }
814
815    pub fn find_static_overloads_by_arity<'this>(
816        &'this self,
817        name: StringView<'_>,
818        receiver_style: bool,
819        arity: usize,
820    ) -> Vec<FunctionOverloadReference<'this, 'f>> {
821        ffi::FunctionRegistry_find_static_overloads_by_arity(self, name, receiver_style, arity)
822    }
823
824    pub fn find_lazy_overloads<'this>(
825        &'this self,
826        name: StringView<'_>,
827        receiver_style: bool,
828        types: Span<'_, Kind>,
829    ) -> Vec<LazyOverload<'this>> {
830        ffi::FunctionRegistry_find_lazy_overloads(self, name, receiver_style, types)
831    }
832
833    pub fn find_lazy_overloads_by_arity<'this>(
834        &'this self,
835        name: StringView<'_>,
836        receiver_style: bool,
837        arity: usize,
838    ) -> Vec<LazyOverload<'this>> {
839        ffi::FunctionRegistry_find_lazy_overloads_by_arity(self, name, receiver_style, arity)
840    }
841
842    pub fn list_functions<'this>(&'this self) -> FunctionRegistryIterator<'this> {
843        ffi::FunctionRegistry_list_functions(self)
844    }
845}
846
847// FunctionRegistryIterator
848#[repr(C)]
849pub struct FunctionRegistryIterator<'a>(crate::Rep<'a, usize, 1>);
850
851unsafe impl<'a> cxx::ExternType for FunctionRegistryIterator<'a> {
852    type Id = cxx::type_id!("rust::cel_cxx::FunctionRegistryIterator");
853    type Kind = cxx::kind::Trivial;
854}
855
856impl<'a> Drop for FunctionRegistryIterator<'a> {
857    fn drop(&mut self) {
858        ffi::FunctionRegistryIterator_drop(self);
859    }
860}
861
862//unsafe impl<'a> Send for FunctionRegistryIterator<'a> {}
863//unsafe impl<'a> Sync for FunctionRegistryIterator<'a> {}
864
865impl<'a> std::iter::Iterator for FunctionRegistryIterator<'a> {
866    type Item = (
867        cxx::UniquePtr<cxx::CxxString>,
868        cxx::UniquePtr<cxx::CxxVector<FunctionDescriptor>>,
869    );
870
871    fn next(&mut self) -> Option<Self::Item> {
872        let mut key = cxx::UniquePtr::null();
873        let mut value = cxx::UniquePtr::null();
874        if ffi::FunctionRegistryIterator_next(self, &mut key, &mut value) {
875            Some((key, value))
876        } else {
877            None
878        }
879    }
880}
881
882// Program
883pub use ffi::Program;
884unsafe impl<'a, 'f> Send for Program<'a, 'f> {}
885unsafe impl<'a, 'f> Sync for Program<'a, 'f> {}
886
887impl<'a, 'f> Program<'a, 'f> {
888    pub fn evaluate<'a2, 'f2>(
889        &self,
890        arena: &'a2 Arena,
891        message_factory: Option<&MessageFactory>,
892        activation: &Activation<'f2>,
893    ) -> Result<cxx::UniquePtr<Value<'a2>>, Status> {
894        let mut result = cxx::UniquePtr::null();
895        let status = match message_factory {
896            Some(message_factory) => {
897                ffi::Program_evaluate(self, arena, message_factory, activation, &mut result)
898            }
899            None => ffi::Program_evaluate2(self, arena, activation, &mut result),
900        };
901        if status.is_ok() {
902            Ok(result)
903        } else {
904            Err(status)
905        }
906    }
907}
908
909impl<'a, 'f> std::fmt::Debug for Program<'a, 'f> {
910    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
911        let ptr = self as *const Program<'a, 'f>;
912        write!(f, "Program {{ ptr: {ptr:p} }}")
913    }
914}
915
916// Function
917pub use ffi::Function;
918unsafe impl<'f> Send for Function<'f> {}
919unsafe impl<'f> Sync for Function<'f> {}
920
921impl<'f> Function<'f> {
922    pub fn new<T: FfiFunction + 'f>(ffi_function: T) -> cxx::UniquePtr<Self> {
923        ffi::Function_new(Box::new(AnyFfiFunction::new(ffi_function)))
924    }
925}
926
927// FfiFunction
928pub trait FfiFunction {
929    fn invoke<'a>(
930        &self,
931        args: Span<'_, Value<'a>>,
932        descriptor_pool: &'a DescriptorPool,
933        message_factory: &'a MessageFactory,
934        arena: &'a Arena,
935        overload_id: Span<'_, cxx::CxxString>,
936    ) -> Result<cxx::UniquePtr<Value<'a>>, Status>;
937}
938
939// AnyFfiFunction
940struct AnyFfiFunction<'f>(Box<dyn FfiFunction + 'f>);
941
942impl<'f> AnyFfiFunction<'f> {
943    fn new<T: FfiFunction + 'f>(function: T) -> Self {
944        Self(Box::new(function))
945    }
946
947    fn invoke<'a>(
948        &self,
949        args: Span<'_, Value<'a>>,
950        descriptor_pool: &'a DescriptorPool,
951        message_factory: &'a MessageFactory,
952        arena: &'a Arena,
953        overload_id: Span<'_, cxx::CxxString>,
954        result: Pin<&mut Value<'a>>,
955    ) -> Status {
956        match self
957            .0
958            .invoke(args, descriptor_pool, message_factory, arena, overload_id)
959        {
960            Ok(mut value) => {
961                result.swap(value.pin_mut());
962                Status::ok()
963            }
964            Err(status) => status,
965        }
966    }
967}
968
969// TypeRegistry
970pub use ffi::TypeRegistry;
971unsafe impl<'d, 'a> Send for TypeRegistry<'d, 'a> {}
972unsafe impl<'d, 'a> Sync for TypeRegistry<'d, 'a> {}