filter_expr/
expr.rs

1
2use crate::{Error, Transform, TransformContext, TransformResult};
3
4/// The expression.
5///
6/// It is an AST of the filter expression.
7#[derive(Debug, Clone, PartialEq)]
8pub enum Expr {
9    Field(String),
10    Str(String),
11    I64(i64),
12    F64(f64),
13    Bool(bool),
14    Null,
15    Array(Vec<Expr>),
16
17    FuncCall(String, Vec<Expr>),
18    MethodCall(String, Box<Expr>, Vec<Expr>),
19
20    Gt(Box<Expr>, Box<Expr>),
21    Lt(Box<Expr>, Box<Expr>),
22    Ge(Box<Expr>, Box<Expr>),
23    Le(Box<Expr>, Box<Expr>),
24    Eq(Box<Expr>, Box<Expr>),
25    Ne(Box<Expr>, Box<Expr>),
26    In(Box<Expr>, Box<Expr>),
27
28    And(Vec<Expr>),
29    Or(Vec<Expr>),
30    Not(Box<Expr>),
31}
32
33#[allow(unused)]
34impl Expr {
35    pub(crate) fn field_<T: Into<String>>(field: T) -> Self {
36        Self::Field(field.into())
37    }
38
39    pub(crate) fn str_<T: Into<String>>(value: T) -> Self {
40        Self::Str(value.into())
41    }
42
43    pub(crate) fn i64_<T: Into<i64>>(value: T) -> Self {
44        Self::I64(value.into())
45    }
46
47    pub(crate) fn f64_<T: Into<f64>>(value: T) -> Self {
48        Self::F64(value.into())
49    }
50
51    pub(crate) fn bool_<T: Into<bool>>(value: T) -> Self {
52        Self::Bool(value.into())
53    }
54
55    pub(crate) fn null_() -> Self {
56        Self::Null
57    }
58
59    pub(crate) fn array_<T: Into<Vec<Expr>>>(value: T) -> Self {
60        Self::Array(value.into())
61    }
62
63    pub(crate) fn func_call_(func: impl Into<String>, args: Vec<Expr>) -> Self {
64        Self::FuncCall(func.into(), args)
65    }
66
67    pub(crate) fn method_call_(obj: Expr, method: impl Into<String>, args: Vec<Expr>) -> Self {
68        Self::MethodCall(method.into(), Box::new(obj), args)
69    }
70
71    pub(crate) fn gt_(left: Expr, right: Expr) -> Self {
72        Self::Gt(Box::new(left), Box::new(right))
73    }
74
75    pub(crate) fn lt_(left: Expr, right: Expr) -> Self {
76        Self::Lt(Box::new(left), Box::new(right))
77    }
78
79    pub(crate) fn ge_(left: Expr, right: Expr) -> Self {
80        Self::Ge(Box::new(left), Box::new(right))
81    }
82
83    pub(crate) fn le_(left: Expr, right: Expr) -> Self {
84        Self::Le(Box::new(left), Box::new(right))
85    }
86
87    pub(crate) fn eq_(left: Expr, right: Expr) -> Self {
88        Self::Eq(Box::new(left), Box::new(right))
89    }
90
91    pub(crate) fn ne_(left: Expr, right: Expr) -> Self {
92        Self::Ne(Box::new(left), Box::new(right))
93    }
94
95    pub(crate) fn in_(left: Expr, right: Expr) -> Self {
96        Self::In(Box::new(left), Box::new(right))
97    }
98
99    pub(crate) fn and_<T: Into<Vec<Expr>>>(value: T) -> Self {
100        Self::And(value.into())
101    }
102
103    pub(crate) fn or_<T: Into<Vec<Expr>>>(value: T) -> Self {
104        Self::Or(value.into())
105    }
106
107    pub(crate) fn not_(self) -> Self {
108        Self::Not(Box::new(self))
109    }
110}
111
112impl Expr {
113    /// Recursively transform an expression using the provided transformer.
114    ///
115    /// ```rust
116    /// use filter_expr::{Expr, Transform};
117    /// use async_trait::async_trait;
118    ///
119    /// struct MyTransformer;
120    ///
121    /// #[async_trait]
122    /// impl Transform for MyTransformer {
123    ///     async fn transform(&mut self, expr: Expr) -> Result<Expr, filter_expr::Error> {
124    ///         // Transform the expression before recursing
125    ///         Ok(match expr {
126    ///             Expr::Field(name) if name == "old_name" => {
127    ///                 Expr::Field("new_name".to_string())
128    ///             }
129    ///             other => other,
130    ///         })
131    ///     }
132    /// }
133    ///
134    /// # #[tokio::main]
135    /// # async fn main() {
136    /// let expr = Expr::Field("old_name".to_string());
137    /// let mut transformer = MyTransformer;
138    /// let result = expr.transform(&mut transformer).await.unwrap();
139    /// assert_eq!(result, Expr::Field("new_name".to_string()));
140    /// # }
141    /// ```
142    pub async fn transform<F: Transform>(self, transformer: &mut F) -> Result<Expr, Error> {
143        let ctx = TransformContext { depth: 0 };
144
145        return Self::transform_expr(transformer, self, ctx).await;
146    }
147
148    async fn transform_expr<F: Transform>(transformer: &mut F, expr: Expr, ctx: TransformContext) -> Result<Expr, Error> {
149        let this = transformer.transform(expr, ctx.clone()).await;
150
151        match this {
152            TransformResult::Continue(expr) => {
153                return Box::pin(Self::transform_children(transformer, expr, ctx)).await;
154            }
155            TransformResult::Stop(expr) => {
156                return Ok(expr);
157            }
158            TransformResult::Err(err) => {
159                return Err(Error::Transform(err));
160            }
161        }
162    }
163
164    async fn transform_children<F: Transform>(transformer: &mut F, expr: Expr, mut ctx: TransformContext) -> Result<Expr, Error> {
165        ctx.depth += 1;
166
167        Ok(match expr {
168            // Do nothing if the expression have no children.
169            Expr::Field(name) => Expr::Field(name),
170            Expr::Str(value) => Expr::Str(value),
171            Expr::I64(value) => Expr::I64(value),
172            Expr::F64(value) => Expr::F64(value),
173            Expr::Bool(value) => Expr::Bool(value),
174            Expr::Null => Expr::Null,
175            Expr::Array(value) => Expr::Array(value),
176
177            Expr::FuncCall(func, args) => {
178                let mut transformed_args = Vec::new();
179                for arg in args {
180                    transformed_args.push(Self::transform_expr(transformer, arg, ctx.clone()).await?);
181                }
182                Expr::FuncCall(func, transformed_args)
183            }
184            Expr::MethodCall(method, obj, args) => {
185                let obj = Box::new(Self::transform_expr(transformer, *obj, ctx.clone()).await?);
186                let mut transformed_args = Vec::new();
187                for arg in args {
188                    transformed_args.push(Self::transform_expr(transformer, arg, ctx.clone()).await?);
189                }
190                Expr::MethodCall(method, obj, transformed_args)
191            }
192
193            Expr::Gt(left, right) => {
194                let left = Box::new(Self::transform_expr(transformer, *left, ctx.clone()).await?);
195                let right = Box::new(Self::transform_expr(transformer, *right, ctx).await?);
196                Expr::Gt(left, right)
197            }
198            Expr::Lt(left, right) => {
199                let left = Box::new(Self::transform_expr(transformer, *left, ctx.clone()).await?);
200                let right = Box::new(Self::transform_expr(transformer, *right, ctx).await?);
201                Expr::Lt(left, right)
202            }
203            Expr::Ge(left, right) => {
204                let left = Box::new(Self::transform_expr(transformer, *left, ctx.clone()).await?);
205                let right = Box::new(Self::transform_expr(transformer, *right, ctx).await?);
206                Expr::Ge(left, right)
207            }
208            Expr::Le(left, right) => {
209                let left = Box::new(Self::transform_expr(transformer, *left, ctx.clone()).await?);
210                let right = Box::new(Self::transform_expr(transformer, *right, ctx).await?);
211                Expr::Le(left, right)
212            }
213            Expr::Eq(left, right) => {
214                let left = Box::new(Self::transform_expr(transformer, *left, ctx.clone()).await?);
215                let right = Box::new(Self::transform_expr(transformer, *right, ctx).await?);
216                Expr::Eq(left, right)
217            }
218            Expr::Ne(left, right) => {
219                let left = Box::new(Self::transform_expr(transformer, *left, ctx.clone()).await?);
220                let right = Box::new(Self::transform_expr(transformer, *right, ctx).await?);
221                Expr::Ne(left, right)
222            }
223            Expr::In(left, right) => {
224                let left = Box::new(Self::transform_expr(transformer, *left, ctx.clone()).await?);
225                let right = Box::new(Self::transform_expr(transformer, *right, ctx).await?);
226                Expr::In(left, right)
227            }
228            Expr::And(exprs) => {
229                let mut transformed_exprs = Vec::new();
230                for e in exprs {
231                    transformed_exprs.push(Self::transform_expr(transformer, e, ctx.clone()).await?);
232                }
233                Expr::And(transformed_exprs)
234            }
235            Expr::Or(exprs) => {
236                let mut transformed_exprs = Vec::new();
237                for e in exprs {
238                    transformed_exprs.push(Self::transform_expr(transformer, e, ctx.clone()).await?);
239                }
240                Expr::Or(transformed_exprs)
241            }
242            Expr::Not(expr) => {
243                let expr = Box::new(Self::transform_expr(transformer, *expr, ctx).await?);
244                Expr::Not(expr)
245            }
246        })
247    }
248}