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