1use crate::absl::Status;
2use crate::checker::{
3 CheckerLibrary, CheckerOptions, TypeChecker, TypeCheckerSubset,
4 TypeCheckerBuilderConfigurer, FunctionPredicate,
5 TypeCheckerBuilder, ValidationResult,
6};
7use crate::parser::{
8 ParserOptions, Parser, ParserBuilder, ParserLibrary, ParserLibrarySubset,
9 ParserBuilderConfigurer, MacroPredicate,
10};
11use crate::protobuf::DescriptorPool;
12use std::pin::Pin;
13
14#[cxx::bridge]
15mod ffi {
16 #[namespace = "absl"]
17 unsafe extern "C++" {
18 include!(<absl/status/status.h>);
19 type Status = super::Status;
20 }
21
22 #[namespace = "google::protobuf"]
23 unsafe extern "C++" {
24 include!(<google/protobuf/descriptor.h>);
25 type DescriptorPool = super::DescriptorPool;
26 }
27
28 #[namespace = "cel"]
29 unsafe extern "C++" {
30 include!(<compiler/compiler.h>);
31 type ParserOptions = super::ParserOptions;
32 type CheckerOptions = super::CheckerOptions;
33 type ParserBuilderConfigurer = super::ParserBuilderConfigurer;
34 type TypeCheckerBuilderConfigurer = super::TypeCheckerBuilderConfigurer;
35 type ParserBuilder = super::ParserBuilder;
36 type ParserLibrary = super::ParserLibrary;
37 type CheckerLibrary = super::CheckerLibrary;
38 type TypeCheckerSubset = super::TypeCheckerSubset;
39 type ParserLibrarySubset = super::ParserLibrarySubset;
40 type TypeChecker = super::TypeChecker;
41 type Parser = super::Parser;
42 type TypeCheckerBuilder<'a> = super::TypeCheckerBuilder<'a>;
43 type ValidationResult = super::ValidationResult;
44
45 type Compiler<'a>;
46 #[rust_name = "type_checker"]
47 fn GetTypeChecker<'a>(self: &Compiler<'a>) -> &TypeChecker;
48 #[rust_name = "parser"]
49 fn GetParser<'a>(self: &Compiler<'a>) -> &Parser;
50
51 type CompilerBuilder<'a>;
52 #[rust_name = "checker_builder"]
53 fn GetCheckerBuilder<'a>(
54 self: Pin<&mut CompilerBuilder<'a>>,
55 ) -> Pin<&mut TypeCheckerBuilder<'a>>;
56 #[rust_name = "parser_builder"]
57 fn GetParserBuilder<'a>(self: Pin<&mut CompilerBuilder<'a>>) -> Pin<&mut ParserBuilder>;
58
59 type CompilerLibrary;
60 type CompilerLibrarySubset;
61 type CompilerOptions;
62 }
63
64 #[namespace = "rust::cel_cxx"]
65 unsafe extern "C++" {
66 include!(<cel-cxx-ffi/include/absl.h>);
67 include!(<cel-cxx-ffi/include/compiler.h>);
68
69 type MacroPredicate = super::MacroPredicate;
70 type FunctionPredicate = super::FunctionPredicate;
71
72 fn Compiler_compile(
74 compiler: &Compiler,
75 source: &[u8],
76 description: &str,
77 result: &mut UniquePtr<ValidationResult>,
78 ) -> Status;
79
80 fn CompilerBuilder_new<'a>(
82 descriptor_pool: SharedPtr<DescriptorPool>,
83 options: &CompilerOptions,
84 result: &mut UniquePtr<CompilerBuilder<'a>>,
85 ) -> Status;
86
87 fn CompilerBuilder_add_library<'a>(
88 compiler_builder: Pin<&mut CompilerBuilder<'a>>,
89 library: UniquePtr<CompilerLibrary>,
90 ) -> Status;
91
92 fn CompilerBuilder_build<'a>(
93 compiler_builder: Pin<&mut CompilerBuilder<'a>>,
94 result: &mut UniquePtr<Compiler<'a>>,
95 ) -> Status;
96
97 fn CompilerLibrary_new_standard() -> UniquePtr<CompilerLibrary>;
99 fn CompilerLibrary_new_optional() -> UniquePtr<CompilerLibrary>;
100 fn CompilerLibrary_from_checker_library(
101 checker_library: UniquePtr<CheckerLibrary>,
102 ) -> UniquePtr<CompilerLibrary>;
103 fn CompilerLibrary_from_parser_library(
104 parser_library: UniquePtr<ParserLibrary>,
105 ) -> UniquePtr<CompilerLibrary>;
106
107 fn CompilerLibrary_new(id: &CxxString) -> UniquePtr<CompilerLibrary>;
108 fn CompilerLibrary_set_parser_configurer(
109 compiler_library: Pin<&mut CompilerLibrary>,
110 parser_configurer: UniquePtr<ParserBuilderConfigurer>,
111 );
112 fn CompilerLibrary_set_checker_configurer(
113 compiler_library: Pin<&mut CompilerLibrary>,
114 checker_configurer: UniquePtr<TypeCheckerBuilderConfigurer>,
115 );
116 fn CompilerLibrary_id<'a>(compiler_library: &'a CompilerLibrary) -> &'a CxxString;
117
118 fn CompilerLibrarySubset_from_parser_library_subset(
120 parser_library_subset: UniquePtr<ParserLibrarySubset>,
121 ) -> UniquePtr<CompilerLibrarySubset>;
122 fn CompilerLibrarySubset_from_checker_library_subset(
123 checker_library_subset: UniquePtr<TypeCheckerSubset>,
124 ) -> UniquePtr<CompilerLibrarySubset>;
125
126 fn CompilerLibrarySubset_new(library_id: &CxxString) -> UniquePtr<CompilerLibrarySubset>;
127 fn CompilerLibrarySubset_set_macro_predicate(
128 compiler_library_subset: Pin<&mut CompilerLibrarySubset>,
129 should_include_macro: UniquePtr<MacroPredicate>,
130 );
131 fn CompilerLibrarySubset_set_function_predicate(
132 compiler_library_subset: Pin<&mut CompilerLibrarySubset>,
133 should_include_overload: UniquePtr<FunctionPredicate>,
134 );
135 fn CompilerLibrarySubset_library_id<'a>(compiler_library_subset: &'a CompilerLibrarySubset) -> &'a CxxString;
136
137 fn CompilerOptions_new() -> UniquePtr<CompilerOptions>;
139
140 fn CompilerOptions_parser_options(compiler_options: &CompilerOptions) -> &ParserOptions;
142 fn CompilerOptions_parser_options_mut(
143 compiler_options: Pin<&mut CompilerOptions>,
144 ) -> Pin<&mut ParserOptions>;
145 fn CompilerOptions_checker_options(compiler_options: &CompilerOptions) -> &CheckerOptions;
146 fn CompilerOptions_checker_options_mut(
147 compiler_options: Pin<&mut CompilerOptions>,
148 ) -> Pin<&mut CheckerOptions>;
149 }
150}
151
152pub use ffi::Compiler;
153unsafe impl<'a> Send for Compiler<'a> {}
154unsafe impl<'a> Sync for Compiler<'a> {}
155
156impl<'a> Compiler<'a> {
157 pub fn compile(
158 &self,
159 source: &[u8],
160 description: Option<&str>,
161 ) -> Result<cxx::UniquePtr<ValidationResult>, Status> {
162 let description = description.unwrap_or("<input>");
163 let mut result = cxx::UniquePtr::null();
164 let status = ffi::Compiler_compile(self, source, description, &mut result);
165 if status.is_ok() {
166 Ok(result)
167 } else {
168 Err(status)
169 }
170 }
171}
172
173impl<'a> std::fmt::Debug for Compiler<'a> {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 write!(
176 f,
177 "Compiler {{ type_checker: {:?}, parser: {:?} }}",
178 self.type_checker(),
179 self.parser(),
180 )
181 }
182}
183
184pub use ffi::CompilerBuilder;
185unsafe impl<'a> Send for CompilerBuilder<'a> {}
186unsafe impl<'a> Sync for CompilerBuilder<'a> {}
187
188impl<'a> CompilerBuilder<'a> {
189 pub fn new(
190 descriptor_pool: cxx::SharedPtr<DescriptorPool>,
191 options: &CompilerOptions,
192 ) -> Result<cxx::UniquePtr<Self>, Status> {
193 let mut result = cxx::UniquePtr::null();
194 let status = ffi::CompilerBuilder_new(descriptor_pool, options, &mut result);
195 if status.is_ok() {
196 Ok(result)
197 } else {
198 Err(status)
199 }
200 }
201
202 pub fn add_library(
203 self: Pin<&mut Self>,
204 library: cxx::UniquePtr<CompilerLibrary>,
205 ) -> Result<(), Status> {
206 let status = ffi::CompilerBuilder_add_library(self, library);
207 if status.is_ok() {
208 Ok(())
209 } else {
210 Err(status)
211 }
212 }
213
214 pub fn build(self: Pin<&mut Self>) -> Result<cxx::UniquePtr<Compiler<'a>>, Status> {
215 let mut result = cxx::UniquePtr::null();
216 let status = ffi::CompilerBuilder_build(self, &mut result);
217 if status.is_ok() {
218 Ok(result)
219 } else {
220 Err(status)
221 }
222 }
223}
224
225impl<'a> std::fmt::Debug for CompilerBuilder<'a> {
226 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
227 write!(f, "CompilerBuilder {{ ptr: {:p} }}", self as *const Self)
228 }
229}
230
231pub use ffi::CompilerLibrary;
233unsafe impl Send for CompilerLibrary {}
234unsafe impl Sync for CompilerLibrary {}
235
236impl CompilerLibrary {
237 pub fn new(id: &cxx::CxxString) -> cxx::UniquePtr<Self> {
238 ffi::CompilerLibrary_new(id)
239 }
240
241 pub fn set_parser_configurer(
242 self: Pin<&mut Self>,
243 parser_configurer: cxx::UniquePtr<ParserBuilderConfigurer>,
244 ) {
245 ffi::CompilerLibrary_set_parser_configurer(self, parser_configurer);
246 }
247
248 pub fn set_checker_configurer(
249 self: Pin<&mut Self>,
250 checker_configurer: cxx::UniquePtr<TypeCheckerBuilderConfigurer>,
251 ) {
252 ffi::CompilerLibrary_set_checker_configurer(self, checker_configurer);
253 }
254
255 pub fn new_standard() -> cxx::UniquePtr<Self> {
256 ffi::CompilerLibrary_new_standard()
257 }
258
259 pub fn new_optional() -> cxx::UniquePtr<Self> {
260 ffi::CompilerLibrary_new_optional()
261 }
262
263 pub fn from_checker_library(
264 checker_library: cxx::UniquePtr<CheckerLibrary>,
265 ) -> cxx::UniquePtr<Self> {
266 ffi::CompilerLibrary_from_checker_library(checker_library)
267 }
268
269 pub fn from_parser_library(
270 parser_library: cxx::UniquePtr<ParserLibrary>,
271 ) -> cxx::UniquePtr<Self> {
272 ffi::CompilerLibrary_from_parser_library(parser_library)
273 }
274
275 pub fn id(&self) -> &cxx::CxxString {
276 ffi::CompilerLibrary_id(self)
277 }
278}
279
280pub use ffi::CompilerLibrarySubset;
282unsafe impl Send for CompilerLibrarySubset {}
283unsafe impl Sync for CompilerLibrarySubset {}
284
285impl CompilerLibrarySubset {
286 pub fn new(library_id: &cxx::CxxString) -> cxx::UniquePtr<Self> {
287 ffi::CompilerLibrarySubset_new(library_id)
288 }
289
290 pub fn set_macro_predicate(
291 self: Pin<&mut Self>,
292 macro_predicate: cxx::UniquePtr<MacroPredicate>,
293 ) {
294 ffi::CompilerLibrarySubset_set_macro_predicate(self, macro_predicate);
295 }
296
297 pub fn set_function_predicate(
298 self: Pin<&mut Self>,
299 function_predicate: cxx::UniquePtr<FunctionPredicate>,
300 ) {
301 ffi::CompilerLibrarySubset_set_function_predicate(self, function_predicate);
302 }
303
304 pub fn library_id(&self) -> &cxx::CxxString {
305 ffi::CompilerLibrarySubset_library_id(self)
306 }
307
308 pub fn from_parser_library_subset(
309 parser_library_subset: cxx::UniquePtr<ParserLibrarySubset>,
310 ) -> cxx::UniquePtr<Self> {
311 ffi::CompilerLibrarySubset_from_parser_library_subset(parser_library_subset)
312 }
313
314 pub fn from_checker_library_subset(
315 checker_library_subset: cxx::UniquePtr<TypeCheckerSubset>,
316 ) -> cxx::UniquePtr<Self> {
317 ffi::CompilerLibrarySubset_from_checker_library_subset(checker_library_subset)
318 }
319}
320
321pub use ffi::CompilerOptions;
323unsafe impl Send for CompilerOptions {}
324unsafe impl Sync for CompilerOptions {}
325
326impl CompilerOptions {
327 pub fn new() -> cxx::UniquePtr<Self> {
328 let mut options = ffi::CompilerOptions_new();
329 *options
330 .pin_mut()
331 .parser_options_mut()
332 .enable_optional_syntax_mut() = true;
333 options
334 }
335
336 pub fn parser_options(&self) -> &ParserOptions {
337 ffi::CompilerOptions_parser_options(self)
338 }
339
340 pub fn parser_options_mut(self: Pin<&mut Self>) -> Pin<&mut ParserOptions> {
341 ffi::CompilerOptions_parser_options_mut(self)
342 }
343
344 pub fn checker_options(&self) -> &CheckerOptions {
345 ffi::CompilerOptions_checker_options(self)
346 }
347
348 pub fn checker_options_mut(self: Pin<&mut Self>) -> Pin<&mut CheckerOptions> {
349 ffi::CompilerOptions_checker_options_mut(self)
350 }
351}