Skip to main content

tank_core/expression/
expression.rs

1use crate::{
2    DynQuery, ExpressionVisitor, GenericSqlWriter, OpPrecedence, Operand, Value,
3    writer::{Context, SqlWriter},
4};
5use std::{fmt::Debug, mem};
6
7/// Renderable SQL expression.
8pub trait Expression: OpPrecedence + Send + Sync + Debug {
9    /// Render the expression into SQL.
10    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery);
11    /// Match the expression.
12    fn accept_visitor(
13        &self,
14        matcher: &mut dyn ExpressionVisitor,
15        writer: &dyn SqlWriter,
16        context: &mut Context,
17        _out: &mut DynQuery,
18    ) -> bool;
19    /// Convert expression to an identifier string.
20    fn as_identifier(&self, context: &mut Context) -> String {
21        let mut out = DynQuery::new(String::new());
22        let writer = GenericSqlWriter::new();
23        self.write_query(&writer, context, &mut out);
24        mem::take(out.buffer())
25    }
26}
27
28impl<T: Expression> Expression for &T {
29    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
30        (*self).write_query(writer, context, out);
31    }
32    fn accept_visitor(
33        &self,
34        matcher: &mut dyn ExpressionVisitor,
35        writer: &dyn SqlWriter,
36        context: &mut Context,
37        out: &mut DynQuery,
38    ) -> bool {
39        (*self).accept_visitor(matcher, writer, context, out)
40    }
41    fn as_identifier(&self, context: &mut Context) -> String {
42        (*self).as_identifier(context)
43    }
44}
45
46impl Expression for &dyn Expression {
47    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
48        (*self).write_query(writer, context, out);
49    }
50    fn accept_visitor(
51        &self,
52        matcher: &mut dyn ExpressionVisitor,
53        writer: &dyn SqlWriter,
54        context: &mut Context,
55        out: &mut DynQuery,
56    ) -> bool {
57        (*self).accept_visitor(matcher, writer, context, out)
58    }
59    fn as_identifier(&self, context: &mut Context) -> String {
60        (*self).as_identifier(context)
61    }
62}
63
64impl Expression for () {
65    fn write_query(&self, _writer: &dyn SqlWriter, _context: &mut Context, _out: &mut DynQuery) {}
66    fn accept_visitor(
67        &self,
68        _matcher: &mut dyn ExpressionVisitor,
69        _writer: &dyn SqlWriter,
70        _context: &mut Context,
71        _out: &mut DynQuery,
72    ) -> bool {
73        false
74    }
75}
76
77impl Expression for bool {
78    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
79        writer.write_value_bool(context, out, *self);
80    }
81    fn accept_visitor(
82        &self,
83        matcher: &mut dyn ExpressionVisitor,
84        writer: &dyn SqlWriter,
85        context: &mut Context,
86        out: &mut DynQuery,
87    ) -> bool {
88        matcher.visit_operand(writer, context, out, &Operand::LitBool(*self))
89    }
90}
91
92impl Expression for &'static str {
93    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
94        writer.write_value_string(context, out, self);
95    }
96    fn accept_visitor(
97        &self,
98        matcher: &mut dyn ExpressionVisitor,
99        writer: &dyn SqlWriter,
100        context: &mut Context,
101        out: &mut DynQuery,
102    ) -> bool {
103        matcher.visit_operand(writer, context, out, &Operand::LitStr(*self))
104    }
105}
106
107impl Expression for Value {
108    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
109        writer.write_value(context, out, self);
110    }
111    fn accept_visitor(
112        &self,
113        matcher: &mut dyn ExpressionVisitor,
114        writer: &dyn SqlWriter,
115        context: &mut Context,
116        out: &mut DynQuery,
117    ) -> bool {
118        matcher.visit_operand(writer, context, out, &Operand::Value(self))
119    }
120}
121
122impl<'a, T: Expression> From<&'a T> for &'a dyn Expression {
123    fn from(value: &'a T) -> Self {
124        value as &'a dyn Expression
125    }
126}