Skip to main content

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) -> &CxxString;
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        // TypeRegistry — enum registration
310        fn TypeRegistry_register_enums_from_file_descriptor_set<'d, 'a>(
311            type_registry: Pin<&mut TypeRegistry<'d, 'a>>,
312            descriptor_pool: &DescriptorPool,
313            file_descriptor_set_bytes: &[u8],
314        ) -> Status;
315
316        include!(<cel-cxx-ffi/include/optional.h>);
317        fn EnableOptionalTypes(runtime_builder: Pin<&mut RuntimeBuilder>) -> Status;
318    }
319    #[namespace = "rust::cel_cxx"]
320    extern "Rust" {
321        type AnyFfiActivation<'f>;
322        #[cxx_name = "FindVariable"]
323        unsafe fn find_variable<'f, 'a>(
324            self: &AnyFfiActivation<'f>,
325            name: &str,
326            descriptor_pool: &'a DescriptorPool,
327            message_factory: &'a MessageFactory,
328            arena: &'a Arena,
329            result: &mut UniquePtr<Value<'a>>,
330        ) -> Status;
331        #[cxx_name = "FindFunctionOverloads"]
332        unsafe fn find_function_overloads<'this, 'f>(
333            self: &'this AnyFfiActivation<'f>,
334            name: &str,
335        ) -> Vec<FunctionOverloadReference<'this, 'f>>;
336
337        type AnyFfiFunction<'f>;
338        #[cxx_name = "Invoke"]
339        unsafe fn invoke<'f, 'a>(
340            self: &AnyFfiFunction<'f>,
341            args: Span_Value<'_, 'a>,
342            descriptor_pool: &'a DescriptorPool,
343            message_factory: &'a MessageFactory,
344            arena: &'a Arena,
345            overload_id: Span_CxxString<'_>,
346            result: Pin<&mut Value<'a>>,
347        ) -> Status;
348    }
349
350    impl<'a, 'f> Vec<FunctionOverloadReference<'a, 'f>> {}
351    impl<'a> Vec<LazyOverload<'a>> {}
352}
353
354// Activation
355pub use ffi::Activation;
356unsafe impl<'f> Send for Activation<'f> {}
357unsafe impl<'f> Sync for Activation<'f> {}
358
359impl<'f> Activation<'f> {
360    pub fn new<T: FfiActivation<'f> + 'f>(ffi: T) -> cxx::UniquePtr<Self> {
361        ffi::Activation_new(Box::new(AnyFfiActivation::new(ffi)))
362    }
363}
364
365// FunctionOverloadReference
366#[repr(C)]
367#[derive(Clone, Copy)]
368pub struct FunctionOverloadReference<'a, 'f> {
369    descriptor: &'a FunctionDescriptor,
370    implementation: &'a Function<'f>,
371}
372
373unsafe impl<'a, 'f> cxx::ExternType for FunctionOverloadReference<'a, 'f> {
374    type Id = cxx::type_id!("cel::FunctionOverloadReference");
375    type Kind = cxx::kind::Trivial;
376}
377
378impl<'a, 'f> FunctionOverloadReference<'a, 'f> {
379    pub fn new(descriptor: &'a FunctionDescriptor, implementation: &'a Function<'f>) -> Self {
380        Self {
381            descriptor,
382            implementation,
383        }
384    }
385
386    pub fn descriptor(&self) -> &'a FunctionDescriptor {
387        self.descriptor
388    }
389
390    pub fn implementation(&self) -> &'a Function<'f> {
391        self.implementation
392    }
393}
394
395// FunctionProvider
396pub use ffi::FunctionProvider;
397unsafe impl Send for FunctionProvider {}
398unsafe impl Sync for FunctionProvider {}
399
400// LazyOverload
401#[repr(C)]
402#[derive(Clone, Copy)]
403pub struct LazyOverload<'a> {
404    descriptor: &'a FunctionDescriptor,
405    function_provider: &'a FunctionProvider,
406}
407
408unsafe impl<'a> cxx::ExternType for LazyOverload<'a> {
409    type Id = cxx::type_id!("rust::cel_cxx::LazyOverload");
410    type Kind = cxx::kind::Trivial;
411}
412
413impl<'a> LazyOverload<'a> {
414    pub fn new(
415        descriptor: &'a FunctionDescriptor,
416        function_provider: &'a FunctionProvider,
417    ) -> Self {
418        Self {
419            descriptor,
420            function_provider,
421        }
422    }
423
424    pub fn descriptor(&self) -> &'a FunctionDescriptor {
425        self.descriptor
426    }
427
428    pub fn function_provider(&self) -> &'a FunctionProvider {
429        self.function_provider
430    }
431}
432
433// FfiActivation
434pub trait FfiActivation<'f> {
435    fn find_variable<'a>(
436        &self,
437        name: &str,
438        descriptor_pool: &'a DescriptorPool,
439        message_factory: &'a MessageFactory,
440        arena: &'a Arena,
441    ) -> Result<Option<cxx::UniquePtr<Value<'a>>>, Status>;
442
443    fn find_function_overloads<'this>(
444        &'this self,
445        name: &str,
446    ) -> Vec<FunctionOverloadReference<'this, 'f>>;
447}
448
449// AnyFfiActivation
450struct AnyFfiActivation<'f>(Box<dyn FfiActivation<'f> + 'f>);
451
452impl<'f> AnyFfiActivation<'f> {
453    fn new<T: FfiActivation<'f> + 'f>(activation: T) -> Self {
454        Self(Box::new(activation))
455    }
456
457    fn find_variable<'a>(
458        &self,
459        name: &str,
460        descriptor_pool: &'a DescriptorPool,
461        message_factory: &'a MessageFactory,
462        arena: &'a Arena,
463        result: &mut cxx::UniquePtr<Value<'a>>,
464    ) -> Status {
465        *result = cxx::UniquePtr::null();
466
467        match self
468            .0
469            .find_variable(name, descriptor_pool, message_factory, arena)
470        {
471            Ok(Some(value)) => {
472                *result = value;
473                Status::ok()
474            }
475            Ok(None) => Status::ok(),
476            Err(status) => status,
477        }
478    }
479
480    fn find_function_overloads<'this>(
481        &'this self,
482        name: &str,
483    ) -> Vec<FunctionOverloadReference<'this, 'f>> {
484        self.0.find_function_overloads(name)
485    }
486}
487
488// Runtime
489pub use ffi::Runtime;
490unsafe impl<'a, 'f> Send for Runtime<'a, 'f> {}
491unsafe impl<'a, 'f> Sync for Runtime<'a, 'f> {}
492
493impl<'a, 'f> Runtime<'a, 'f> {
494    pub fn create_program(
495        &self,
496        ast: cxx::UniquePtr<Ast>,
497    ) -> Result<cxx::UniquePtr<Program<'a, 'f>>, Status> {
498        let mut result = cxx::UniquePtr::null();
499        let status = ffi::Runtime_create_program(self, ast, &mut result);
500        if status.is_ok() {
501            Ok(result)
502        } else {
503            Err(status)
504        }
505    }
506}
507
508impl<'a, 'f> std::fmt::Debug for Runtime<'a, 'f> {
509    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
510        let ptr = self as *const Runtime<'a, 'f>;
511        write!(f, "Runtime {{ ptr: {ptr:p} }}")
512    }
513}
514
515// RuntimeBuilder
516pub use ffi::RuntimeBuilder;
517unsafe impl<'a, 'f> Send for RuntimeBuilder<'a, 'f> {}
518unsafe impl<'a, 'f> Sync for RuntimeBuilder<'a, 'f> {}
519
520impl<'a, 'f> RuntimeBuilder<'a, 'f> {
521    pub fn new(
522        descriptor_pool: cxx::SharedPtr<DescriptorPool>,
523        options: &RuntimeOptions,
524    ) -> Result<cxx::UniquePtr<Self>, Status> {
525        let mut result = cxx::UniquePtr::null();
526        let status = ffi::RuntimeBuilder_new(descriptor_pool, options, &mut result);
527        if status.is_ok() {
528            Ok(result)
529        } else {
530            Err(status)
531        }
532    }
533
534    pub fn enable_standard(self: Pin<&mut Self>, options: &RuntimeOptions) -> Result<(), Status> {
535        let status = ffi::RegisterStandardFunctions(self.function_registry(), options);
536        if status.is_ok() {
537            Ok(())
538        } else {
539            Err(status)
540        }
541    }
542
543    #[allow(unused_variables)]
544    pub fn enable_optional(self: Pin<&mut Self>, options: &RuntimeOptions) -> Result<(), Status> {
545        let status = ffi::EnableOptionalTypes(self);
546        if status.is_ok() {
547            Ok(())
548        } else {
549            Err(status)
550        }
551    }
552
553    pub fn options(&self) -> &RuntimeOptions {
554        ffi::RuntimeBuilder_options(self)
555    }
556
557    pub fn build(self: Pin<&mut Self>) -> Result<cxx::UniquePtr<Runtime<'a, 'f>>, Status> {
558        let mut result = cxx::UniquePtr::null();
559        let status = ffi::RuntimeBuilder_build(self, &mut result);
560        if status.is_ok() {
561            Ok(result)
562        } else {
563            Err(status)
564        }
565    }
566}
567
568impl<'a, 'f> std::fmt::Debug for RuntimeBuilder<'a, 'f> {
569    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
570        let ptr = self as *const RuntimeBuilder<'a, 'f>;
571        write!(f, "RuntimeBuilder {{ ptr: {ptr:p} }}")
572    }
573}
574
575// RuntimeOptions
576#[repr(i32)]
577#[derive(Clone, Copy, PartialEq, Eq, Default)]
578pub enum UnknownProcessingOptions {
579    #[default]
580    /// No unknown processing.
581    Disabled,
582    /// Only attributes supported.
583    AttributeOnly,
584    /// Attributes and functions supported. Function results are dependent on the
585    /// logic for handling unknown_attributes, so clients must opt in to both.
586    AttributeAndFunction,
587}
588
589unsafe impl cxx::ExternType for UnknownProcessingOptions {
590    type Id = cxx::type_id!("cel::UnknownProcessingOptions");
591    type Kind = cxx::kind::Trivial;
592}
593
594pub use ffi::RuntimeOptions;
595unsafe impl Send for RuntimeOptions {}
596unsafe impl Sync for RuntimeOptions {}
597
598impl RuntimeOptions {
599    pub fn new() -> cxx::UniquePtr<Self> {
600        ffi::RuntimeOptions_new()
601    }
602
603    pub fn container(&self) -> &cxx::CxxString {
604        ffi::RuntimeOptions_container(self)
605    }
606
607    pub fn container_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut cxx::CxxString> {
608        ffi::RuntimeOptions_container_mut(self)
609    }
610
611    pub fn unknown_processing(&self) -> UnknownProcessingOptions {
612        ffi::RuntimeOptions_unknown_processing(self)
613    }
614
615    pub fn unknown_processing_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut UnknownProcessingOptions {
616        ffi::RuntimeOptions_unknown_processing_mut(self)
617    }
618
619    pub fn enable_missing_attribute_errors(&self) -> bool {
620        ffi::RuntimeOptions_enable_missing_attribute_errors(self)
621    }
622
623    pub fn enable_missing_attribute_errors_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
624        ffi::RuntimeOptions_enable_missing_attribute_errors_mut(self)
625    }
626
627    pub fn enable_timestamp_duration_overflow_errors(&self) -> bool {
628        ffi::RuntimeOptions_enable_timestamp_duration_overflow_errors(self)
629    }
630
631    pub fn enable_timestamp_duration_overflow_errors_mut<'a>(
632        self: Pin<&'a mut Self>,
633    ) -> &'a mut bool {
634        ffi::RuntimeOptions_enable_timestamp_duration_overflow_errors_mut(self)
635    }
636
637    pub fn short_circuiting(&self) -> bool {
638        ffi::RuntimeOptions_short_circuiting(self)
639    }
640
641    pub fn short_circuiting_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
642        ffi::RuntimeOptions_short_circuiting_mut(self)
643    }
644
645    pub fn enable_comprehension(&self) -> bool {
646        ffi::RuntimeOptions_enable_comprehension(self)
647    }
648
649    pub fn enable_comprehension_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
650        ffi::RuntimeOptions_enable_comprehension_mut(self)
651    }
652
653    pub fn comprehension_max_iterations(&self) -> i32 {
654        ffi::RuntimeOptions_comprehension_max_iterations(self)
655    }
656
657    pub fn comprehension_max_iterations_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
658        ffi::RuntimeOptions_comprehension_max_iterations_mut(self)
659    }
660
661    pub fn enable_comprehension_list_append(&self) -> bool {
662        ffi::RuntimeOptions_enable_comprehension_list_append(self)
663    }
664
665    pub fn enable_comprehension_list_append_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
666        ffi::RuntimeOptions_enable_comprehension_list_append_mut(self)
667    }
668
669    pub fn enable_regex(&self) -> bool {
670        ffi::RuntimeOptions_enable_regex(self)
671    }
672
673    pub fn enable_regex_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
674        ffi::RuntimeOptions_enable_regex_mut(self)
675    }
676
677    pub fn regex_max_program_size(&self) -> i32 {
678        ffi::RuntimeOptions_regex_max_program_size(self)
679    }
680
681    pub fn regex_max_program_size_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
682        ffi::RuntimeOptions_regex_max_program_size_mut(self)
683    }
684
685    pub fn enable_string_conversion(&self) -> bool {
686        ffi::RuntimeOptions_enable_string_conversion(self)
687    }
688
689    pub fn enable_string_conversion_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
690        ffi::RuntimeOptions_enable_string_conversion_mut(self)
691    }
692
693    pub fn enable_string_concat(&self) -> bool {
694        ffi::RuntimeOptions_enable_string_concat(self)
695    }
696
697    pub fn enable_string_concat_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
698        ffi::RuntimeOptions_enable_string_concat_mut(self)
699    }
700
701    pub fn enable_list_concat(&self) -> bool {
702        ffi::RuntimeOptions_enable_list_concat(self)
703    }
704
705    pub fn enable_list_concat_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
706        ffi::RuntimeOptions_enable_list_concat_mut(self)
707    }
708
709    pub fn enable_list_contains(&self) -> bool {
710        ffi::RuntimeOptions_enable_list_contains(self)
711    }
712
713    pub fn enable_list_contains_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
714        ffi::RuntimeOptions_enable_list_contains_mut(self)
715    }
716
717    pub fn fail_on_warnings(&self) -> bool {
718        ffi::RuntimeOptions_fail_on_warnings(self)
719    }
720
721    pub fn fail_on_warnings_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
722        ffi::RuntimeOptions_fail_on_warnings_mut(self)
723    }
724
725    pub fn enable_qualified_type_identifiers(&self) -> bool {
726        ffi::RuntimeOptions_enable_qualified_type_identifiers(self)
727    }
728
729    pub fn enable_qualified_type_identifiers_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
730        ffi::RuntimeOptions_enable_qualified_type_identifiers_mut(self)
731    }
732
733    pub fn enable_heterogeneous_equality(&self) -> bool {
734        ffi::RuntimeOptions_enable_heterogeneous_equality(self)
735    }
736
737    pub fn enable_heterogeneous_equality_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
738        ffi::RuntimeOptions_enable_heterogeneous_equality_mut(self)
739    }
740
741    pub fn enable_empty_wrapper_null_unboxing(&self) -> bool {
742        ffi::RuntimeOptions_enable_empty_wrapper_null_unboxing(self)
743    }
744
745    pub fn enable_empty_wrapper_null_unboxing_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
746        ffi::RuntimeOptions_enable_empty_wrapper_null_unboxing_mut(self)
747    }
748
749    pub fn enable_lazy_bind_initialization(&self) -> bool {
750        ffi::RuntimeOptions_enable_lazy_bind_initialization(self)
751    }
752
753    pub fn enable_lazy_bind_initialization_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
754        ffi::RuntimeOptions_enable_lazy_bind_initialization_mut(self)
755    }
756
757    pub fn max_recursion_depth(&self) -> i32 {
758        ffi::RuntimeOptions_max_recursion_depth(self)
759    }
760
761    pub fn max_recursion_depth_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
762        ffi::RuntimeOptions_max_recursion_depth_mut(self)
763    }
764
765    pub fn enable_recursive_tracing(&self) -> bool {
766        ffi::RuntimeOptions_enable_recursive_tracing(self)
767    }
768
769    pub fn enable_recursive_tracing_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
770        ffi::RuntimeOptions_enable_recursive_tracing_mut(self)
771    }
772
773    pub fn enable_fast_builtins(&self) -> bool {
774        ffi::RuntimeOptions_enable_fast_builtins(self)
775    }
776
777    pub fn enable_fast_builtins_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
778        ffi::RuntimeOptions_enable_fast_builtins_mut(self)
779    }
780}
781
782// FunctionDescriptor
783pub use ffi::FunctionDescriptor;
784unsafe impl Send for FunctionDescriptor {}
785unsafe impl Sync for FunctionDescriptor {}
786
787impl FunctionDescriptor {
788    pub fn new(
789        name: &str,
790        receiver_style: bool,
791        types: &[Kind],
792        is_strict: bool,
793    ) -> cxx::UniquePtr<Self> {
794        ffi::FunctionDescriptor_new(name, receiver_style, types, is_strict)
795    }
796
797    pub fn new_shared(
798        name: &str,
799        receiver_style: bool,
800        types: &[Kind],
801        is_strict: bool,
802    ) -> cxx::SharedPtr<Self> {
803        ffi::FunctionDescriptor_new_shared(name, receiver_style, types, is_strict)
804    }
805}
806
807// FunctionRegistry
808pub use ffi::FunctionRegistry;
809unsafe impl<'f> Send for FunctionRegistry<'f> {}
810unsafe impl<'f> Sync for FunctionRegistry<'f> {}
811
812impl<'f> FunctionRegistry<'f> {
813    pub fn find_static_overloads<'this>(
814        &'this self,
815        name: StringView<'_>,
816        receiver_style: bool,
817        types: Span<'_, Kind>,
818    ) -> Vec<FunctionOverloadReference<'this, 'f>> {
819        ffi::FunctionRegistry_find_static_overloads(self, name, receiver_style, types)
820    }
821
822    pub fn find_static_overloads_by_arity<'this>(
823        &'this self,
824        name: StringView<'_>,
825        receiver_style: bool,
826        arity: usize,
827    ) -> Vec<FunctionOverloadReference<'this, 'f>> {
828        ffi::FunctionRegistry_find_static_overloads_by_arity(self, name, receiver_style, arity)
829    }
830
831    pub fn find_lazy_overloads<'this>(
832        &'this self,
833        name: StringView<'_>,
834        receiver_style: bool,
835        types: Span<'_, Kind>,
836    ) -> Vec<LazyOverload<'this>> {
837        ffi::FunctionRegistry_find_lazy_overloads(self, name, receiver_style, types)
838    }
839
840    pub fn find_lazy_overloads_by_arity<'this>(
841        &'this self,
842        name: StringView<'_>,
843        receiver_style: bool,
844        arity: usize,
845    ) -> Vec<LazyOverload<'this>> {
846        ffi::FunctionRegistry_find_lazy_overloads_by_arity(self, name, receiver_style, arity)
847    }
848
849    pub fn list_functions<'this>(&'this self) -> FunctionRegistryIterator<'this> {
850        ffi::FunctionRegistry_list_functions(self)
851    }
852}
853
854// FunctionRegistryIterator
855#[repr(C)]
856pub struct FunctionRegistryIterator<'a>(crate::Rep<'a, usize, 1>);
857
858unsafe impl<'a> cxx::ExternType for FunctionRegistryIterator<'a> {
859    type Id = cxx::type_id!("rust::cel_cxx::FunctionRegistryIterator");
860    type Kind = cxx::kind::Trivial;
861}
862
863impl<'a> Drop for FunctionRegistryIterator<'a> {
864    fn drop(&mut self) {
865        ffi::FunctionRegistryIterator_drop(self);
866    }
867}
868
869//unsafe impl<'a> Send for FunctionRegistryIterator<'a> {}
870//unsafe impl<'a> Sync for FunctionRegistryIterator<'a> {}
871
872impl<'a> std::iter::Iterator for FunctionRegistryIterator<'a> {
873    type Item = (
874        cxx::UniquePtr<cxx::CxxString>,
875        cxx::UniquePtr<cxx::CxxVector<FunctionDescriptor>>,
876    );
877
878    fn next(&mut self) -> Option<Self::Item> {
879        let mut key = cxx::UniquePtr::null();
880        let mut value = cxx::UniquePtr::null();
881        if ffi::FunctionRegistryIterator_next(self, &mut key, &mut value) {
882            Some((key, value))
883        } else {
884            None
885        }
886    }
887}
888
889// Program
890pub use ffi::Program;
891unsafe impl<'a, 'f> Send for Program<'a, 'f> {}
892unsafe impl<'a, 'f> Sync for Program<'a, 'f> {}
893
894impl<'a, 'f> Program<'a, 'f> {
895    pub fn evaluate<'a2, 'f2>(
896        &self,
897        arena: &'a2 Arena,
898        message_factory: Option<&MessageFactory>,
899        activation: &Activation<'f2>,
900    ) -> Result<cxx::UniquePtr<Value<'a2>>, Status> {
901        let mut result = cxx::UniquePtr::null();
902        let status = match message_factory {
903            Some(message_factory) => {
904                ffi::Program_evaluate(self, arena, message_factory, activation, &mut result)
905            }
906            None => ffi::Program_evaluate2(self, arena, activation, &mut result),
907        };
908        if status.is_ok() {
909            Ok(result)
910        } else {
911            Err(status)
912        }
913    }
914}
915
916impl<'a, 'f> std::fmt::Debug for Program<'a, 'f> {
917    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
918        let ptr = self as *const Program<'a, 'f>;
919        write!(f, "Program {{ ptr: {ptr:p} }}")
920    }
921}
922
923// Function
924pub use ffi::Function;
925unsafe impl<'f> Send for Function<'f> {}
926unsafe impl<'f> Sync for Function<'f> {}
927
928impl<'f> Function<'f> {
929    pub fn new<T: FfiFunction + 'f>(ffi_function: T) -> cxx::UniquePtr<Self> {
930        ffi::Function_new(Box::new(AnyFfiFunction::new(ffi_function)))
931    }
932}
933
934// FfiFunction
935pub trait FfiFunction {
936    fn invoke<'a>(
937        &self,
938        args: Span<'_, Value<'a>>,
939        descriptor_pool: &'a DescriptorPool,
940        message_factory: &'a MessageFactory,
941        arena: &'a Arena,
942        overload_id: Span<'_, cxx::CxxString>,
943    ) -> Result<cxx::UniquePtr<Value<'a>>, Status>;
944}
945
946// AnyFfiFunction
947struct AnyFfiFunction<'f>(Box<dyn FfiFunction + 'f>);
948
949impl<'f> AnyFfiFunction<'f> {
950    fn new<T: FfiFunction + 'f>(function: T) -> Self {
951        Self(Box::new(function))
952    }
953
954    fn invoke<'a>(
955        &self,
956        args: Span<'_, Value<'a>>,
957        descriptor_pool: &'a DescriptorPool,
958        message_factory: &'a MessageFactory,
959        arena: &'a Arena,
960        overload_id: Span<'_, cxx::CxxString>,
961        result: Pin<&mut Value<'a>>,
962    ) -> Status {
963        match self
964            .0
965            .invoke(args, descriptor_pool, message_factory, arena, overload_id)
966        {
967            Ok(mut value) => {
968                result.swap(value.pin_mut());
969                Status::ok()
970            }
971            Err(status) => status,
972        }
973    }
974}
975
976// TypeRegistry
977pub use ffi::TypeRegistry;
978unsafe impl<'d, 'a> Send for TypeRegistry<'d, 'a> {}
979unsafe impl<'d, 'a> Sync for TypeRegistry<'d, 'a> {}
980
981impl<'d, 'a> TypeRegistry<'d, 'a> {
982    pub fn register_enums_from_file_descriptor_set(
983        self: Pin<&mut Self>,
984        descriptor_pool: &DescriptorPool,
985        file_descriptor_set_bytes: &[u8],
986    ) -> Result<(), Status> {
987        let status = ffi::TypeRegistry_register_enums_from_file_descriptor_set(
988            self,
989            descriptor_pool,
990            file_descriptor_set_bytes,
991        );
992        if status.is_ok() {
993            Ok(())
994        } else {
995            Err(status)
996        }
997    }
998}