tank_core/expression/
binary_op.rs1use crate::{
2 DynQuery, Expression, ExpressionVisitor, GenericSqlWriter, OpPrecedence,
3 writer::{Context, SqlWriter},
4};
5use proc_macro2::TokenStream;
6use quote::{ToTokens, TokenStreamExt, quote};
7use std::mem;
8
9#[derive(Clone, Copy, PartialEq, Eq, Debug)]
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 fn accept_visitor(
75 &self,
76 matcher: &mut dyn ExpressionVisitor,
77 writer: &dyn SqlWriter,
78 context: &mut Context,
79 out: &mut DynQuery,
80 ) -> bool {
81 matcher.visit_binary_op(
82 writer,
83 context,
84 out,
85 &BinaryOp {
86 op: self.op,
87 lhs: &self.lhs,
88 rhs: &self.rhs,
89 },
90 )
91 }
92 fn as_identifier(&self, context: &mut Context) -> String {
93 if self.op == BinaryOpType::Alias {
94 self.rhs.as_identifier(context)
95 } else {
96 let mut out = DynQuery::new(String::new());
97 let writer = GenericSqlWriter::new();
98 self.write_query(&writer, context, &mut out);
99 mem::take(out.buffer())
100 }
101 }
102}
103
104impl ToTokens for BinaryOpType {
105 fn to_tokens(&self, tokens: &mut TokenStream) {
106 let v = format!("{self:?}");
107 tokens.append_all(quote!(::tank::BinaryOpType::#v));
108 }
109}