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}