gluesql_core/ast/
operator.rs

1use {
2    crate::ast::ToSql,
3    serde::{Deserialize, Serialize},
4};
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub enum UnaryOperator {
8    Plus,
9    Minus,
10    Not,
11    Factorial,
12    BitwiseNot,
13}
14
15impl ToSql for UnaryOperator {
16    fn to_sql(&self) -> String {
17        match self {
18            UnaryOperator::Plus => "+".to_owned(),
19            UnaryOperator::Minus => "-".to_owned(),
20            UnaryOperator::Not => "NOT ".to_owned(),
21            UnaryOperator::Factorial => "!".to_owned(),
22            UnaryOperator::BitwiseNot => "~".to_owned(),
23        }
24    }
25}
26
27#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
28pub enum BinaryOperator {
29    Plus,
30    Minus,
31    Multiply,
32    Divide,
33    Modulo,
34    StringConcat,
35    Gt,
36    Lt,
37    GtEq,
38    LtEq,
39    Eq,
40    NotEq,
41    And,
42    Or,
43    Xor,
44    BitwiseAnd,
45    BitwiseShiftLeft,
46    BitwiseShiftRight,
47}
48
49impl ToSql for BinaryOperator {
50    fn to_sql(&self) -> String {
51        match self {
52            BinaryOperator::Plus => "+".to_owned(),
53            BinaryOperator::Minus => "-".to_owned(),
54            BinaryOperator::Multiply => "*".to_owned(),
55            BinaryOperator::Divide => "/".to_owned(),
56            BinaryOperator::Modulo => "%".to_owned(),
57            BinaryOperator::StringConcat => "+".to_owned(),
58            BinaryOperator::Gt => ">".to_owned(),
59            BinaryOperator::Lt => "<".to_owned(),
60            BinaryOperator::GtEq => ">=".to_owned(),
61            BinaryOperator::LtEq => "<=".to_owned(),
62            BinaryOperator::Eq => "=".to_owned(),
63            BinaryOperator::NotEq => "<>".to_owned(),
64            BinaryOperator::And => "AND".to_owned(),
65            BinaryOperator::Or => "OR".to_owned(),
66            BinaryOperator::Xor => "XOR".to_owned(),
67            BinaryOperator::BitwiseAnd => "&".to_owned(),
68            BinaryOperator::BitwiseShiftLeft => "<<".to_owned(),
69            BinaryOperator::BitwiseShiftRight => ">>".to_owned(),
70        }
71    }
72}
73
74#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
75pub enum IndexOperator {
76    Gt,
77    Lt,
78    GtEq,
79    LtEq,
80    Eq,
81}
82
83impl IndexOperator {
84    pub fn reverse(self) -> Self {
85        use IndexOperator::*;
86
87        match self {
88            Gt => Lt,
89            Lt => Gt,
90            GtEq => LtEq,
91            LtEq => GtEq,
92            Eq => Eq,
93        }
94    }
95}
96
97impl From<IndexOperator> for BinaryOperator {
98    fn from(index_op: IndexOperator) -> Self {
99        match index_op {
100            IndexOperator::Gt => BinaryOperator::Gt,
101            IndexOperator::Lt => BinaryOperator::Lt,
102            IndexOperator::GtEq => BinaryOperator::GtEq,
103            IndexOperator::LtEq => BinaryOperator::LtEq,
104            IndexOperator::Eq => BinaryOperator::Eq,
105        }
106    }
107}
108
109#[cfg(test)]
110mod tests {
111    use {
112        crate::ast::{AstLiteral, BinaryOperator, Expr, ToSql, UnaryOperator},
113        bigdecimal::BigDecimal,
114    };
115    #[test]
116    fn to_sql() {
117        assert_eq!(
118            "1 + 2",
119            Expr::BinaryOp {
120                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1)))),
121                op: BinaryOperator::Plus,
122                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(2))))
123            }
124            .to_sql()
125        );
126
127        assert_eq!(
128            "100 - 10",
129            Expr::BinaryOp {
130                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(100)))),
131                op: BinaryOperator::Minus,
132                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(10))))
133            }
134            .to_sql()
135        );
136
137        assert_eq!(
138            "1024 * 1024",
139            Expr::BinaryOp {
140                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024)))),
141                op: BinaryOperator::Multiply,
142                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024))))
143            }
144            .to_sql()
145        );
146
147        assert_eq!(
148            "1024 / 8",
149            Expr::BinaryOp {
150                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024)))),
151                op: BinaryOperator::Divide,
152                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(8))))
153            }
154            .to_sql()
155        );
156
157        assert_eq!(
158            "1024 % 4",
159            &Expr::BinaryOp {
160                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024)))),
161                op: BinaryOperator::Modulo,
162                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(4))))
163            }
164            .to_sql()
165        );
166
167        assert_eq!(
168            "'Glue' + 'SQL'",
169            &Expr::BinaryOp {
170                left: Box::new(Expr::Literal(AstLiteral::QuotedString("Glue".to_owned()))),
171                op: BinaryOperator::StringConcat,
172                right: Box::new(Expr::Literal(AstLiteral::QuotedString("SQL".to_owned())))
173            }
174            .to_sql()
175        );
176        assert_eq!(
177            "1024 > 4",
178            &Expr::BinaryOp {
179                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024)))),
180                op: BinaryOperator::Gt,
181                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(4))))
182            }
183            .to_sql()
184        );
185        assert_eq!(
186            "8 < 1024",
187            &Expr::BinaryOp {
188                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(8)))),
189                op: BinaryOperator::Lt,
190                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024))))
191            }
192            .to_sql()
193        );
194        assert_eq!(
195            "1024 >= 1024",
196            &Expr::BinaryOp {
197                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024)))),
198                op: BinaryOperator::GtEq,
199                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024))))
200            }
201            .to_sql()
202        );
203        assert_eq!(
204            "8 <= 8",
205            &Expr::BinaryOp {
206                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(8)))),
207                op: BinaryOperator::LtEq,
208                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(8))))
209            }
210            .to_sql()
211        );
212        assert_eq!(
213            "1024 = 1024",
214            &Expr::BinaryOp {
215                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024)))),
216                op: BinaryOperator::Eq,
217                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024))))
218            }
219            .to_sql()
220        );
221        assert_eq!(
222            "1024 <> 1024",
223            &Expr::BinaryOp {
224                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024)))),
225                op: BinaryOperator::NotEq,
226                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1024))))
227            }
228            .to_sql()
229        );
230        assert_eq!(
231            "1 << 2",
232            &Expr::BinaryOp {
233                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1)))),
234                op: BinaryOperator::BitwiseShiftLeft,
235                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(2))))
236            }
237            .to_sql()
238        );
239        assert_eq!(
240            "1 >> 2",
241            &Expr::BinaryOp {
242                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1)))),
243                op: BinaryOperator::BitwiseShiftRight,
244                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(2))))
245            }
246            .to_sql()
247        );
248        assert_eq!(
249            r#""condition_0" AND "condition_1""#,
250            &Expr::BinaryOp {
251                left: Box::new(Expr::Identifier("condition_0".to_owned())),
252                op: BinaryOperator::And,
253                right: Box::new(Expr::Identifier("condition_1".to_owned()))
254            }
255            .to_sql()
256        );
257        assert_eq!(
258            r#""condition_0" OR "condition_1""#,
259            &Expr::BinaryOp {
260                left: Box::new(Expr::Identifier("condition_0".to_owned())),
261                op: BinaryOperator::Or,
262                right: Box::new(Expr::Identifier("condition_1".to_owned()))
263            }
264            .to_sql()
265        );
266        assert_eq!(
267            r#""condition_0" XOR "condition_1""#,
268            &Expr::BinaryOp {
269                left: Box::new(Expr::Identifier("condition_0".to_owned())),
270                op: BinaryOperator::Xor,
271                right: Box::new(Expr::Identifier("condition_1".to_owned()))
272            }
273            .to_sql()
274        );
275        assert_eq!(
276            "+8",
277            Expr::UnaryOp {
278                op: UnaryOperator::Plus,
279                expr: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(8)))),
280            }
281            .to_sql(),
282        );
283
284        assert_eq!(
285            "-8",
286            Expr::UnaryOp {
287                op: UnaryOperator::Minus,
288                expr: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(8)))),
289            }
290            .to_sql(),
291        );
292
293        assert_eq!(
294            r#"NOT "id""#,
295            Expr::UnaryOp {
296                op: UnaryOperator::Not,
297                expr: Box::new(Expr::Identifier("id".to_owned())),
298            }
299            .to_sql(),
300        );
301
302        assert_eq!(
303            "5!",
304            Expr::UnaryOp {
305                op: UnaryOperator::Factorial,
306                expr: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(5)))),
307            }
308            .to_sql(),
309        );
310
311        assert_eq!(
312            "29 & 15",
313            &Expr::BinaryOp {
314                left: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(29)))),
315                op: BinaryOperator::BitwiseAnd,
316                right: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(15))))
317            }
318            .to_sql()
319        );
320
321        assert_eq!(
322            "~1",
323            Expr::UnaryOp {
324                op: UnaryOperator::BitwiseNot,
325                expr: Box::new(Expr::Literal(AstLiteral::Number(BigDecimal::from(1)))),
326            }
327            .to_sql(),
328        )
329    }
330}