1use async_trait::async_trait;
2
3use crate::Error;
4
5#[derive(Debug, Clone, PartialEq)]
9pub enum Expr {
10 Field(String),
11 Str(String),
12 I64(i64),
13 F64(f64),
14 Bool(bool),
15 Null,
16 Array(Vec<Expr>),
17
18 FuncCall(String, Vec<Expr>),
19 MethodCall(String, Box<Expr>, Vec<Expr>),
20
21 Gt(Box<Expr>, Box<Expr>),
22 Lt(Box<Expr>, Box<Expr>),
23 Ge(Box<Expr>, Box<Expr>),
24 Le(Box<Expr>, Box<Expr>),
25 Eq(Box<Expr>, Box<Expr>),
26 Ne(Box<Expr>, Box<Expr>),
27 In(Box<Expr>, Box<Expr>),
28
29 And(Vec<Expr>),
30 Or(Vec<Expr>),
31 Not(Box<Expr>),
32}
33
34#[allow(unused)]
35impl Expr {
36 pub(crate) fn field_<T: Into<String>>(field: T) -> Self {
37 Self::Field(field.into())
38 }
39
40 pub(crate) fn str_<T: Into<String>>(value: T) -> Self {
41 Self::Str(value.into())
42 }
43
44 pub(crate) fn i64_<T: Into<i64>>(value: T) -> Self {
45 Self::I64(value.into())
46 }
47
48 pub(crate) fn f64_<T: Into<f64>>(value: T) -> Self {
49 Self::F64(value.into())
50 }
51
52 pub(crate) fn bool_<T: Into<bool>>(value: T) -> Self {
53 Self::Bool(value.into())
54 }
55
56 pub(crate) fn null_() -> Self {
57 Self::Null
58 }
59
60 pub(crate) fn array_<T: Into<Vec<Expr>>>(value: T) -> Self {
61 Self::Array(value.into())
62 }
63
64 pub(crate) fn func_call_(func: impl Into<String>, args: Vec<Expr>) -> Self {
65 Self::FuncCall(func.into(), args)
66 }
67
68 pub(crate) fn method_call_(obj: Expr, method: impl Into<String>, args: Vec<Expr>) -> Self {
69 Self::MethodCall(method.into(), Box::new(obj), args)
70 }
71
72 pub(crate) fn gt_(left: Expr, right: Expr) -> Self {
73 Self::Gt(Box::new(left), Box::new(right))
74 }
75
76 pub(crate) fn lt_(left: Expr, right: Expr) -> Self {
77 Self::Lt(Box::new(left), Box::new(right))
78 }
79
80 pub(crate) fn ge_(left: Expr, right: Expr) -> Self {
81 Self::Ge(Box::new(left), Box::new(right))
82 }
83
84 pub(crate) fn le_(left: Expr, right: Expr) -> Self {
85 Self::Le(Box::new(left), Box::new(right))
86 }
87
88 pub(crate) fn eq_(left: Expr, right: Expr) -> Self {
89 Self::Eq(Box::new(left), Box::new(right))
90 }
91
92 pub(crate) fn ne_(left: Expr, right: Expr) -> Self {
93 Self::Ne(Box::new(left), Box::new(right))
94 }
95
96 pub(crate) fn in_(left: Expr, right: Expr) -> Self {
97 Self::In(Box::new(left), Box::new(right))
98 }
99
100 pub(crate) fn and_<T: Into<Vec<Expr>>>(value: T) -> Self {
101 Self::And(value.into())
102 }
103
104 pub(crate) fn or_<T: Into<Vec<Expr>>>(value: T) -> Self {
105 Self::Or(value.into())
106 }
107
108 pub(crate) fn not_(self) -> Self {
109 Self::Not(Box::new(self))
110 }
111}
112
113#[async_trait]
141pub trait Transform {
142 async fn transform(&mut self, expr: Expr) -> Result<Expr, Error>
144 where
145 Self: Sized;
146}
147
148impl Expr {
149 pub async fn transform<F: Transform>(self, transformer: &mut F) -> Result<Expr, Error> {
179 let this = transformer.transform(self).await?;
180
181 Ok(match this {
182 Expr::Field(name) => Expr::Field(name),
183 Expr::Str(value) => Expr::Str(value),
184 Expr::I64(value) => Expr::I64(value),
185 Expr::F64(value) => Expr::F64(value),
186 Expr::Bool(value) => Expr::Bool(value),
187 Expr::Null => Expr::Null,
188 Expr::Array(value) => Expr::Array(value),
189
190 Expr::FuncCall(func, args) => {
191 let mut transformed_args = Vec::new();
192 for arg in args {
193 transformed_args.push(transformer.transform(arg).await?);
194 }
195 Expr::FuncCall(func, transformed_args)
196 }
197 Expr::MethodCall(method, obj, args) => {
198 let obj = Box::new(transformer.transform(*obj).await?);
199 let mut transformed_args = Vec::new();
200 for arg in args {
201 transformed_args.push(transformer.transform(arg).await?);
202 }
203 Expr::MethodCall(method, obj, transformed_args)
204 }
205
206 Expr::Gt(left, right) => {
207 let left = Box::new(transformer.transform(*left).await?);
208 let right = Box::new(transformer.transform(*right).await?);
209 Expr::Gt(left, right)
210 }
211 Expr::Lt(left, right) => {
212 let left = Box::new(transformer.transform(*left).await?);
213 let right = Box::new(transformer.transform(*right).await?);
214 Expr::Lt(left, right)
215 }
216 Expr::Ge(left, right) => {
217 let left = Box::new(transformer.transform(*left).await?);
218 let right = Box::new(transformer.transform(*right).await?);
219 Expr::Ge(left, right)
220 }
221 Expr::Le(left, right) => {
222 let left = Box::new(transformer.transform(*left).await?);
223 let right = Box::new(transformer.transform(*right).await?);
224 Expr::Le(left, right)
225 }
226 Expr::Eq(left, right) => {
227 let left = Box::new(transformer.transform(*left).await?);
228 let right = Box::new(transformer.transform(*right).await?);
229 Expr::Eq(left, right)
230 }
231 Expr::Ne(left, right) => {
232 let left = Box::new(transformer.transform(*left).await?);
233 let right = Box::new(transformer.transform(*right).await?);
234 Expr::Ne(left, right)
235 }
236 Expr::In(left, right) => {
237 let left = Box::new(transformer.transform(*left).await?);
238 let right = Box::new(transformer.transform(*right).await?);
239 Expr::In(left, right)
240 }
241 Expr::And(exprs) => {
242 let mut transformed_exprs = Vec::new();
243 for e in exprs {
244 transformed_exprs.push(transformer.transform(e).await?);
245 }
246 Expr::And(transformed_exprs)
247 }
248 Expr::Or(exprs) => {
249 let mut transformed_exprs = Vec::new();
250 for e in exprs {
251 transformed_exprs.push(transformer.transform(e).await?);
252 }
253 Expr::Or(transformed_exprs)
254 }
255 Expr::Not(expr) => {
256 let expr = Box::new(transformer.transform(*expr).await?);
257 Expr::Not(expr)
258 }
259 })
260 }
261}
262
263#[cfg(test)]
264mod tests {
265 use super::*;
266
267 #[tokio::test]
268 async fn test_transform_expr_to_rename_field() {
269 mod rename_field {
270 use super::*;
271
272 pub struct RenameFieldTransformer {
273 pub old_name: String,
274 pub new_name: String,
275 }
276
277 #[async_trait::async_trait]
278 impl Transform for RenameFieldTransformer {
279 async fn transform(&mut self, expr: Expr) -> Result<Expr, Error> {
280 Ok(match expr {
281 Expr::Field(name) if name == self.old_name => {
282 Expr::Field(self.new_name.clone())
283 }
284 _ => expr,
285 })
286 }
287 }
288 }
289
290 let expr = Expr::eq_(
291 Expr::field_("old_name"),
292 Expr::str_("value"),
293 );
294
295 let mut transformer = rename_field::RenameFieldTransformer {
296 old_name: "old_name".to_string(),
297 new_name: "new_name".to_string(),
298 };
299
300 let result = expr.transform(&mut transformer).await.unwrap();
301 assert_eq!(
302 result,
303 Expr::Eq(
304 Box::new(Expr::field_("new_name")),
305 Box::new(Expr::str_("value"))
306 )
307 );
308 }
309
310 #[tokio::test]
311 async fn test_transform_expr_to_load_datas_from_external_datasource() {
312 mod foo {
313 use std::time::Duration;
314
315 use super::*;
316
317 pub struct FooTransformer;
318
319 #[async_trait::async_trait]
320 impl Transform for FooTransformer {
321 async fn transform(&mut self, expr: Expr) -> Result<Expr, Error> {
322 Ok(match expr {
323 Expr::FuncCall(fn_name, args) if fn_name == "is_not_bad" => {
324 if args.len() != 1 {
325 return Err(Error::Transform("expected 1 argument".to_string()));
326 }
327 let datas = load_datas().await;
328 Expr::In(Box::new(args[0].clone()), Box::new(Expr::Array(datas)))
329 }
330 _ => expr,
331 })
332 }
333 }
334
335 async fn load_datas() -> Vec<Expr> {
336 tokio::time::sleep(Duration::from_millis(100)).await;
337
338 vec![
339 Expr::Str("foo".to_string()),
340 Expr::Str("bar".to_string()),
341 ]
342 }
343 }
344
345 let expr = Expr::and_([
346 Expr::func_call_("is_not_bad", vec![Expr::field_("magic")]),
347 Expr::func_call_("is_not_bad", vec![Expr::field_("foobar")]),
348 ]);
349
350 let mut transformer = foo::FooTransformer;
351 let result = expr.transform(&mut transformer).await.unwrap();
352 assert_eq!(result, Expr::and_([
353 Expr::in_(Expr::field_("magic"), Expr::array_([Expr::str_("foo"), Expr::str_("bar")])),
354 Expr::in_(Expr::field_("foobar"), Expr::array_([Expr::str_("foo"), Expr::str_("bar")])),
355 ]));
356 }
357}