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