cel_cxx_ffi/
checker.rs

1use std::pin::Pin;
2
3use crate::absl::{Status, StringView};
4use crate::common::{Ast, FunctionDecl, Source, Type, VariableDecl};
5
6#[cxx::bridge]
7mod ffi {
8    #[namespace = "absl"]
9    unsafe extern "C++" {
10        include!(<absl/status/status.h>);
11        type Status = super::Status;
12        
13        include!(<absl/strings/string_view.h>);
14        type string_view<'a> = super::StringView<'a>;
15    }
16
17    #[namespace = "cel"]
18    unsafe extern "C++" {
19        include!(<checker/type_checker_builder.h>);
20        include!(<checker/checker_options.h>);
21        type Type<'a> = super::Type<'a>;
22        type Ast = super::Ast;
23        type Source = super::Source;
24        type VariableDecl<'a> = super::VariableDecl<'a>;
25        type FunctionDecl<'a> = super::FunctionDecl<'a>;
26
27        type CheckerOptions;
28        type CheckerLibrary;
29
30        type TypeChecker;
31
32        type TypeCheckerBuilder<'a>;
33        #[rust_name = "add_variable"]
34        fn AddVariable<'a>(
35            self: Pin<&mut TypeCheckerBuilder<'a>>,
36            decl: &VariableDecl<'a>,
37        ) -> Status;
38        #[rust_name = "add_function"]
39        fn AddFunction<'a>(
40            self: Pin<&mut TypeCheckerBuilder<'a>>,
41            decl: &FunctionDecl<'a>,
42        ) -> Status;
43        #[rust_name = "merge_function"]
44        fn MergeFunction<'a>(
45            self: Pin<&mut TypeCheckerBuilder<'a>>,
46            decl: &FunctionDecl<'a>,
47        ) -> Status;
48        #[rust_name = "set_expected_type"]
49        fn SetExpectedType<'a>(self: Pin<&mut TypeCheckerBuilder<'a>>, expected_type: &Type<'a>);
50        fn set_container<'a, 'b>(self: Pin<&mut TypeCheckerBuilder<'a>>, container: string_view<'b>);
51        fn options<'this, 'a>(self: &'this TypeCheckerBuilder<'a>) -> &'this CheckerOptions;
52
53        type TypeCheckIssue;
54        fn severity(self: &TypeCheckIssue) -> Severity;
55
56        type ValidationResult;
57        #[rust_name = "is_valid"]
58        fn IsValid(self: &ValidationResult) -> bool;
59    }
60
61    #[namespace = "rust::cel_cxx"]
62    unsafe extern "C++" {
63        include!(<cel-cxx-ffi/include/absl.h>);
64        include!(<cel-cxx-ffi/include/checker.h>);
65        type Severity = super::Severity;
66
67        // CheckerLibrary
68        fn CheckerLibrary_new_optional() -> UniquePtr<CheckerLibrary>;
69        fn CheckerLibrary_new_standard() -> UniquePtr<CheckerLibrary>;
70
71        // CheckerOptions
72        fn CheckerOptions_new() -> UniquePtr<CheckerOptions>;
73
74        // CheckerOptions getters and setters
75        fn CheckerOptions_enable_cross_numeric_comparisons(
76            checker_options: &CheckerOptions,
77        ) -> bool;
78        fn CheckerOptions_enable_cross_numeric_comparisons_mut(
79            checker_options: Pin<&mut CheckerOptions>,
80        ) -> &mut bool;
81        fn CheckerOptions_enable_legacy_null_assignment(checker_options: &CheckerOptions) -> bool;
82        fn CheckerOptions_enable_legacy_null_assignment_mut(
83            checker_options: Pin<&mut CheckerOptions>,
84        ) -> &mut bool;
85        fn CheckerOptions_update_struct_type_names(checker_options: &CheckerOptions) -> bool;
86        fn CheckerOptions_update_struct_type_names_mut(
87            checker_options: Pin<&mut CheckerOptions>,
88        ) -> &mut bool;
89        fn CheckerOptions_allow_well_known_type_context_declarations(
90            checker_options: &CheckerOptions,
91        ) -> bool;
92        fn CheckerOptions_allow_well_known_type_context_declarations_mut(
93            checker_options: Pin<&mut CheckerOptions>,
94        ) -> &mut bool;
95        fn CheckerOptions_max_expression_node_count(checker_options: &CheckerOptions) -> i32;
96        fn CheckerOptions_max_expression_node_count_mut(
97            checker_options: Pin<&mut CheckerOptions>,
98        ) -> &mut i32;
99        fn CheckerOptions_max_error_issues(checker_options: &CheckerOptions) -> i32;
100        fn CheckerOptions_max_error_issues_mut(
101            checker_options: Pin<&mut CheckerOptions>,
102        ) -> &mut i32;
103
104        // TypeCheckerBuilder
105        fn TypeCheckerBuilder_add_library<'a>(
106            type_checker_builder: Pin<&mut TypeCheckerBuilder<'a>>,
107            library: UniquePtr<CheckerLibrary>,
108        ) -> Status;
109
110        // TypeCheckIssue
111        fn TypeCheckIssue_to_display_string(
112            type_check_issue: &TypeCheckIssue,
113            source: &Source,
114        ) -> String;
115
116        // ValidationResult
117        unsafe fn ValidationResult_get_ast(validation_result: &ValidationResult) -> *const Ast;
118        fn ValidationResult_release_ast(
119            validation_result: Pin<&mut ValidationResult>,
120            result: &mut UniquePtr<Ast>,
121        ) -> Status;
122
123        fn ValidationResult_format_error(validation_result: &ValidationResult) -> String;
124    }
125
126    impl UniquePtr<ValidationResult> {}
127}
128
129pub use ffi::CheckerLibrary;
130unsafe impl Send for CheckerLibrary {}
131unsafe impl Sync for CheckerLibrary {}
132
133impl CheckerLibrary {
134    pub fn new_optional() -> cxx::UniquePtr<Self> {
135        ffi::CheckerLibrary_new_optional()
136    }
137
138    pub fn new_standard() -> cxx::UniquePtr<Self> {
139        ffi::CheckerLibrary_new_standard()
140    }
141}
142
143pub use ffi::CheckerOptions;
144unsafe impl Send for CheckerOptions {}
145unsafe impl Sync for CheckerOptions {}
146
147impl CheckerOptions {
148    pub fn new() -> cxx::UniquePtr<Self> {
149        ffi::CheckerOptions_new()
150    }
151
152    pub fn enable_cross_numeric_comparisons(&self) -> bool {
153        ffi::CheckerOptions_enable_cross_numeric_comparisons(self)
154    }
155
156    pub fn enable_cross_numeric_comparisons_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
157        ffi::CheckerOptions_enable_cross_numeric_comparisons_mut(self)
158    }
159
160    pub fn enable_legacy_null_assignment(&self) -> bool {
161        ffi::CheckerOptions_enable_legacy_null_assignment(self)
162    }
163
164    pub fn enable_legacy_null_assignment_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
165        ffi::CheckerOptions_enable_legacy_null_assignment_mut(self)
166    }
167
168    pub fn update_struct_type_names(&self) -> bool {
169        ffi::CheckerOptions_update_struct_type_names(self)
170    }
171
172    pub fn update_struct_type_names_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut bool {
173        ffi::CheckerOptions_update_struct_type_names_mut(self)
174    }
175
176    pub fn allow_well_known_type_context_declarations(&self) -> bool {
177        ffi::CheckerOptions_allow_well_known_type_context_declarations(self)
178    }
179
180    pub fn allow_well_known_type_context_declarations_mut<'a>(
181        self: Pin<&'a mut Self>,
182    ) -> &'a mut bool {
183        ffi::CheckerOptions_allow_well_known_type_context_declarations_mut(self)
184    }
185
186    pub fn max_expression_node_count(&self) -> i32 {
187        ffi::CheckerOptions_max_expression_node_count(self)
188    }
189
190    pub fn max_expression_node_count_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
191        ffi::CheckerOptions_max_expression_node_count_mut(self)
192    }
193
194    pub fn max_error_issues(&self) -> i32 {
195        ffi::CheckerOptions_max_error_issues(self)
196    }
197
198    pub fn max_error_issues_mut<'a>(self: Pin<&'a mut Self>) -> &'a mut i32 {
199        ffi::CheckerOptions_max_error_issues_mut(self)
200    }
201}
202
203pub use ffi::ValidationResult;
204unsafe impl Send for ValidationResult {}
205unsafe impl Sync for ValidationResult {}
206
207impl ValidationResult {
208    pub fn ast(&self) -> Option<&Ast> {
209        unsafe {
210            let ast = ffi::ValidationResult_get_ast(self);
211            ast.as_ref()
212        }
213    }
214
215    pub fn release_ast(self: Pin<&mut Self>) -> Result<cxx::UniquePtr<Ast>, Status> {
216        let mut result = cxx::UniquePtr::null();
217        let status = ffi::ValidationResult_release_ast(self, &mut result);
218        if status.is_ok() {
219            Ok(result)
220        } else {
221            Err(status)
222        }
223    }
224
225    pub fn format_error(&self) -> String {
226        ffi::ValidationResult_format_error(self)
227    }
228}
229
230// Severity
231#[repr(i32)]
232#[derive(Clone, Copy, PartialEq, Eq, Default)]
233pub enum Severity {
234    #[default]
235    Error,
236    Warning,
237    Information,
238    Deprecated,
239}
240
241unsafe impl cxx::ExternType for Severity {
242    type Id = cxx::type_id!("rust::cel_cxx::Severity");
243    type Kind = cxx::kind::Trivial;
244}
245
246// TypeCheckIssue
247pub use ffi::TypeCheckIssue;
248unsafe impl Send for TypeCheckIssue {}
249unsafe impl Sync for TypeCheckIssue {}
250impl TypeCheckIssue {
251    pub fn to_display_string(&self, source: &Source) -> String {
252        ffi::TypeCheckIssue_to_display_string(self, source)
253    }
254}
255
256pub use ffi::TypeChecker;
257unsafe impl Send for TypeChecker {}
258unsafe impl Sync for TypeChecker {}
259
260impl std::fmt::Debug for TypeChecker {
261    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
262        let ptr = self as *const TypeChecker;
263        write!(f, "TypeChecker {{ ptr: {ptr:p} }}")
264    }
265}
266
267pub use ffi::TypeCheckerBuilder;
268unsafe impl<'a> Send for TypeCheckerBuilder<'a> {}
269unsafe impl<'a> Sync for TypeCheckerBuilder<'a> {}
270
271impl<'a> TypeCheckerBuilder<'a> {
272    pub fn add_library(self: Pin<&mut Self>, library: cxx::UniquePtr<CheckerLibrary>) -> Status {
273        ffi::TypeCheckerBuilder_add_library(self, library)
274    }
275}