tank_core/expression/
binary_op.rs

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}