1use crate::absl::Status;
2use crate::checker::{CheckerLibrary, CheckerOptions};
3use crate::checker::{TypeChecker, TypeCheckerBuilder, ValidationResult};
4use crate::parser::ParserOptions;
5use crate::parser::{Parser, ParserBuilder};
6use crate::protobuf::DescriptorPool;
7use std::pin::Pin;
8
9#[cxx::bridge]
10mod ffi {
11 #[namespace = "absl"]
12 unsafe extern "C++" {
13 include!(<absl/status/status.h>);
14 type Status = super::Status;
15 }
16
17 #[namespace = "google::protobuf"]
18 unsafe extern "C++" {
19 include!(<google/protobuf/descriptor.h>);
20 type DescriptorPool = super::DescriptorPool;
21 }
22
23 #[namespace = "cel"]
24 unsafe extern "C++" {
25 include!(<compiler/compiler.h>);
26 type ParserOptions = super::ParserOptions;
27 type CheckerOptions = super::CheckerOptions;
28 type ParserBuilder = super::ParserBuilder;
29 type CheckerLibrary = super::CheckerLibrary;
30 type TypeChecker = super::TypeChecker;
31 type Parser = super::Parser;
32 type TypeCheckerBuilder<'a> = super::TypeCheckerBuilder<'a>;
33 type ValidationResult = super::ValidationResult;
34
35 type Compiler<'a>;
36 #[rust_name = "type_checker"]
37 fn GetTypeChecker<'a>(self: &Compiler<'a>) -> &TypeChecker;
38 #[rust_name = "parser"]
39 fn GetParser<'a>(self: &Compiler<'a>) -> &Parser;
40
41 type CompilerBuilder<'a>;
42 #[rust_name = "checker_builder"]
43 fn GetCheckerBuilder<'a>(
44 self: Pin<&mut CompilerBuilder<'a>>,
45 ) -> Pin<&mut TypeCheckerBuilder<'a>>;
46 #[rust_name = "parser_builder"]
47 fn GetParserBuilder<'a>(self: Pin<&mut CompilerBuilder<'a>>) -> Pin<&mut ParserBuilder>;
48
49 type CompilerLibrary;
50 type CompilerOptions;
51 }
52
53 #[namespace = "rust::cel_cxx"]
54 unsafe extern "C++" {
55 include!(<cel-cxx-ffi/include/absl.h>);
56 include!(<cel-cxx-ffi/include/compiler.h>);
57
58 fn Compiler_compile(
60 compiler: &Compiler,
61 source: &[u8],
62 description: &str,
63 result: &mut UniquePtr<ValidationResult>,
64 ) -> Status;
65
66 fn CompilerBuilder_new<'a>(
68 descriptor_pool: SharedPtr<DescriptorPool>,
69 options: &CompilerOptions,
70 result: &mut UniquePtr<CompilerBuilder<'a>>,
71 ) -> Status;
72
73 fn CompilerBuilder_add_library<'a>(
74 compiler_builder: Pin<&mut CompilerBuilder<'a>>,
75 library: UniquePtr<CompilerLibrary>,
76 ) -> Status;
77
78 fn CompilerBuilder_build<'a>(
79 compiler_builder: Pin<&mut CompilerBuilder<'a>>,
80 result: &mut UniquePtr<Compiler<'a>>,
81 ) -> Status;
82
83 fn CompilerLibrary_new_standard() -> UniquePtr<CompilerLibrary>;
85 fn CompilerLibrary_new_optional() -> UniquePtr<CompilerLibrary>;
86 fn CompilerLibrary_from_checker_library(
87 checker_library: UniquePtr<CheckerLibrary>,
88 ) -> UniquePtr<CompilerLibrary>;
89
90 fn CompilerOptions_new() -> UniquePtr<CompilerOptions>;
92
93 fn CompilerOptions_parser_options(compiler_options: &CompilerOptions) -> &ParserOptions;
95 fn CompilerOptions_parser_options_mut(
96 compiler_options: Pin<&mut CompilerOptions>,
97 ) -> Pin<&mut ParserOptions>;
98 fn CompilerOptions_checker_options(compiler_options: &CompilerOptions) -> &CheckerOptions;
99 fn CompilerOptions_checker_options_mut(
100 compiler_options: Pin<&mut CompilerOptions>,
101 ) -> Pin<&mut CheckerOptions>;
102 }
103}
104
105pub use ffi::Compiler;
106unsafe impl<'a> Send for Compiler<'a> {}
107unsafe impl<'a> Sync for Compiler<'a> {}
108
109impl<'a> Compiler<'a> {
110 pub fn compile(
111 &self,
112 source: &[u8],
113 description: Option<&str>,
114 ) -> Result<cxx::UniquePtr<ValidationResult>, Status> {
115 let description = description.unwrap_or("<input>");
116 let mut result = cxx::UniquePtr::null();
117 let status = ffi::Compiler_compile(self, source, description, &mut result);
118 if status.is_ok() {
119 Ok(result)
120 } else {
121 Err(status)
122 }
123 }
124}
125
126impl<'a> std::fmt::Debug for Compiler<'a> {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 write!(
129 f,
130 "Compiler {{ type_checker: {:?}, parser: {:?} }}",
131 self.type_checker(),
132 self.parser(),
133 )
134 }
135}
136
137pub use ffi::CompilerBuilder;
138unsafe impl<'a> Send for CompilerBuilder<'a> {}
139unsafe impl<'a> Sync for CompilerBuilder<'a> {}
140
141impl<'a> CompilerBuilder<'a> {
142 pub fn new(
143 descriptor_pool: cxx::SharedPtr<DescriptorPool>,
144 options: &CompilerOptions,
145 ) -> Result<cxx::UniquePtr<Self>, Status> {
146 let mut result = cxx::UniquePtr::null();
147 let status = ffi::CompilerBuilder_new(descriptor_pool, options, &mut result);
148 if status.is_ok() {
149 Ok(result)
150 } else {
151 Err(status)
152 }
153 }
154
155 pub fn add_library(
156 self: Pin<&mut Self>,
157 library: cxx::UniquePtr<CompilerLibrary>,
158 ) -> Result<(), Status> {
159 let status = ffi::CompilerBuilder_add_library(self, library);
160 if status.is_ok() {
161 Ok(())
162 } else {
163 Err(status)
164 }
165 }
166
167 pub fn build(self: Pin<&mut Self>) -> Result<cxx::UniquePtr<Compiler<'a>>, Status> {
168 let mut result = cxx::UniquePtr::null();
169 let status = ffi::CompilerBuilder_build(self, &mut result);
170 if status.is_ok() {
171 Ok(result)
172 } else {
173 Err(status)
174 }
175 }
176}
177
178impl<'a> std::fmt::Debug for CompilerBuilder<'a> {
179 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
180 write!(f, "CompilerBuilder {{ ptr: {:p} }}", self as *const Self)
181 }
182}
183
184pub use ffi::CompilerLibrary;
186unsafe impl Send for CompilerLibrary {}
187unsafe impl Sync for CompilerLibrary {}
188
189impl CompilerLibrary {
190 pub fn new_standard() -> cxx::UniquePtr<Self> {
191 ffi::CompilerLibrary_new_standard()
192 }
193
194 pub fn new_optional() -> cxx::UniquePtr<Self> {
195 ffi::CompilerLibrary_new_optional()
196 }
197
198 pub fn from_checker_library(
199 checker_library: cxx::UniquePtr<CheckerLibrary>,
200 ) -> cxx::UniquePtr<Self> {
201 ffi::CompilerLibrary_from_checker_library(checker_library)
202 }
203}
204
205pub use ffi::CompilerOptions;
206unsafe impl Send for CompilerOptions {}
207unsafe impl Sync for CompilerOptions {}
208
209impl CompilerOptions {
210 pub fn new() -> cxx::UniquePtr<Self> {
211 let mut options = ffi::CompilerOptions_new();
212 *options
213 .pin_mut()
214 .parser_options_mut()
215 .enable_optional_syntax_mut() = true;
216 options
217 }
218
219 pub fn parser_options(&self) -> &ParserOptions {
220 ffi::CompilerOptions_parser_options(self)
221 }
222
223 pub fn parser_options_mut(self: Pin<&mut Self>) -> Pin<&mut ParserOptions> {
224 ffi::CompilerOptions_parser_options_mut(self)
225 }
226
227 pub fn checker_options(&self) -> &CheckerOptions {
228 ffi::CompilerOptions_checker_options(self)
229 }
230
231 pub fn checker_options_mut(self: Pin<&mut Self>) -> Pin<&mut CheckerOptions> {
232 ffi::CompilerOptions_checker_options_mut(self)
233 }
234}