1use crate::{
2 Expression, OpPrecedence,
3 writer::{Context, SqlWriter},
4};
5use proc_macro2::TokenStream;
6use quote::{ToTokens, TokenStreamExt, quote};
7use std::fmt::{self, Display, Formatter};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum BinaryOpType {
11 Indexing,
12 Cast,
13 Multiplication,
14 Division,
15 Remainder,
16 Addition,
17 Subtraction,
18 ShiftLeft,
19 ShiftRight,
20 BitwiseAnd,
21 BitwiseOr,
22 Is,
23 IsNot,
24 Like,
25 NotLike,
26 Regexp,
27 NotRegexp,
28 Glob,
29 NotGlob,
30 Equal,
31 NotEqual,
32 Less,
33 Greater,
34 LessEqual,
35 GreaterEqual,
36 And,
37 Or,
38 Alias,
39}
40
41impl OpPrecedence for BinaryOpType {
42 fn precedence(&self, writer: &dyn SqlWriter) -> i32 {
43 writer.expression_binary_op_precedence(self)
44 }
45}
46
47#[derive(Debug)]
48pub struct BinaryOp<L: Expression, R: Expression> {
49 pub op: BinaryOpType,
50 pub lhs: L,
51 pub rhs: R,
52}
53
54impl<L: Expression, R: Expression> OpPrecedence for BinaryOp<L, R> {
55 fn precedence(&self, writer: &dyn SqlWriter) -> i32 {
56 writer.expression_binary_op_precedence(&self.op)
57 }
58}
59
60impl<L: Expression, R: Expression> Expression for BinaryOp<L, R> {
61 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, buff: &mut String) {
62 writer.write_expression_binary_op(
63 context,
64 buff,
65 &BinaryOp {
66 op: self.op,
67 lhs: &self.lhs,
68 rhs: &self.rhs,
69 },
70 )
71 }
72}
73
74impl Display for BinaryOpType {
75 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
76 f.write_str(match self {
77 BinaryOpType::Indexing => "Indexing",
78 BinaryOpType::Cast => "Cast",
79 BinaryOpType::Multiplication => "Multiplication",
80 BinaryOpType::Division => "Division",
81 BinaryOpType::Remainder => "Remainder",
82 BinaryOpType::Addition => "Addition",
83 BinaryOpType::Subtraction => "Subtraction",
84 BinaryOpType::ShiftLeft => "ShiftLeft",
85 BinaryOpType::ShiftRight => "ShiftRight",
86 BinaryOpType::BitwiseAnd => "BitwiseAnd",
87 BinaryOpType::BitwiseOr => "BitwiseOr",
88 BinaryOpType::Is => "Is",
89 BinaryOpType::IsNot => "IsNot",
90 BinaryOpType::Like => "Like",
91 BinaryOpType::NotLike => "NotLike",
92 BinaryOpType::Regexp => "Regexp",
93 BinaryOpType::NotRegexp => "NotRegexp",
94 BinaryOpType::Glob => "Glob",
95 BinaryOpType::NotGlob => "NotGlob",
96 BinaryOpType::Equal => "Equal",
97 BinaryOpType::NotEqual => "NotEqual",
98 BinaryOpType::Less => "Less",
99 BinaryOpType::Greater => "Greater",
100 BinaryOpType::LessEqual => "LessEqual",
101 BinaryOpType::GreaterEqual => "GreaterEqual",
102 BinaryOpType::And => "And",
103 BinaryOpType::Or => "Or",
104 BinaryOpType::Alias => "Alias",
105 })
106 }
107}
108
109impl ToTokens for BinaryOpType {
110 fn to_tokens(&self, tokens: &mut TokenStream) {
111 let v = self.to_string();
112 tokens.append_all(quote!(::tank::BinaryOpType::#v));
113 }
114}