tank_core/expression/
binary_op.rs

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}