1use crate::{
2 writer::{Context, SqlWriter},
3 AsValue, DynQuery, ExpressionVisitor, FixedDecimal, GenericSqlWriter, Interval, OpPrecedence,
4 Operand, Value,
5};
6use rust_decimal::Decimal;
7use std::{borrow::Cow, mem, sync::Arc};
8use time::UtcDateTime;
9use uuid::Uuid;
10
11pub trait Expression: OpPrecedence {
13 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery);
15 fn accept_visitor(
19 &self,
20 _matcher: &mut dyn ExpressionVisitor,
21 _writer: &dyn SqlWriter,
22 _context: &mut Context,
23 _out: &mut DynQuery,
24 ) -> bool {
25 false
26 }
27 fn as_identifier(&self, context: &mut Context) -> String {
29 let mut out = DynQuery::new(String::new());
30 let writer = GenericSqlWriter::new();
31 self.write_query(&writer, context, &mut out);
32 mem::take(out.buffer())
33 }
34}
35
36impl<T: Expression> Expression for &T {
37 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
38 (*self).write_query(writer, context, out);
39 }
40 fn accept_visitor(
41 &self,
42 matcher: &mut dyn ExpressionVisitor,
43 writer: &dyn SqlWriter,
44 context: &mut Context,
45 out: &mut DynQuery,
46 ) -> bool {
47 (*self).accept_visitor(matcher, writer, context, out)
48 }
49 fn as_identifier(&self, context: &mut Context) -> String {
50 (*self).as_identifier(context)
51 }
52}
53
54impl Expression for &dyn Expression {
55 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
56 (*self).write_query(writer, context, out);
57 }
58 fn accept_visitor(
59 &self,
60 matcher: &mut dyn ExpressionVisitor,
61 writer: &dyn SqlWriter,
62 context: &mut Context,
63 out: &mut DynQuery,
64 ) -> bool {
65 (*self).accept_visitor(matcher, writer, context, out)
66 }
67 fn as_identifier(&self, context: &mut Context) -> String {
68 (*self).as_identifier(context)
69 }
70}
71
72impl Expression for () {
73 fn write_query(&self, _writer: &dyn SqlWriter, _context: &mut Context, _out: &mut DynQuery) {}
74}
75
76impl Expression for bool {
77 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
78 writer.write_bool(context, out, *self);
79 }
80 fn accept_visitor(
81 &self,
82 matcher: &mut dyn ExpressionVisitor,
83 writer: &dyn SqlWriter,
84 context: &mut Context,
85 out: &mut DynQuery,
86 ) -> bool {
87 matcher.visit_operand(writer, context, out, &Operand::LitBool(*self))
88 }
89}
90
91impl Expression for &'static str {
92 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
93 writer.write_string(context, out, self);
94 }
95 fn accept_visitor(
96 &self,
97 matcher: &mut dyn ExpressionVisitor,
98 writer: &dyn SqlWriter,
99 context: &mut Context,
100 out: &mut DynQuery,
101 ) -> bool {
102 matcher.visit_operand(writer, context, out, &Operand::LitStr(*self))
103 }
104}
105
106impl Expression for Value {
107 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
108 writer.write_value(context, out, self);
109 }
110 fn accept_visitor(
111 &self,
112 matcher: &mut dyn ExpressionVisitor,
113 writer: &dyn SqlWriter,
114 context: &mut Context,
115 out: &mut DynQuery,
116 ) -> bool {
117 matcher.visit_operand(writer, context, out, &Operand::Value(self))
118 }
119}
120
121impl<'a, T: Expression> From<&'a T> for &'a dyn Expression {
122 fn from(value: &'a T) -> Self {
123 value as &'a dyn Expression
124 }
125}
126
127macro_rules! impl_expression {
128 ($($T:ty),* $(,)?) => {$(
129 impl OpPrecedence for $T {
130 fn precedence(&self, _: &dyn SqlWriter) -> i32 { 0 }
131 }
132 impl Expression for $T {
133 fn write_query(
134 &self,
135 writer: &dyn SqlWriter,
136 context: &mut Context,
137 out: &mut DynQuery,
138 ) {
139 writer.write_value(context, out, &(*self).as_value());
140 }
141 }
142 )*};
143}
144
145impl_expression!(
146 i8,
147 i16,
148 i32,
149 i64,
150 i128,
151 isize,
152 u8,
153 u16,
154 u32,
155 u64,
156 u128,
157 usize,
158 f32,
159 f64,
160 char,
161 Uuid,
162 Decimal,
163 Interval,
164 std::time::Duration,
165 time::Duration,
166 time::Date,
167 time::Time,
168 time::PrimitiveDateTime,
169 time::OffsetDateTime,
170);
171
172#[cfg(feature = "chrono")]
173impl_expression!(
174 chrono::NaiveDate,
175 chrono::NaiveTime,
176 chrono::NaiveDateTime,
177 chrono::DateTime<chrono::FixedOffset>,
178);
179
180impl OpPrecedence for UtcDateTime {
181 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
182 0
183 }
184}
185impl Expression for UtcDateTime {
186 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
187 writer.write_value(
188 context,
189 out,
190 &Value::Timestamp(Some(time::PrimitiveDateTime::new(self.date(), self.time()))),
191 );
192 }
193}
194
195impl OpPrecedence for String {
196 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
197 0
198 }
199}
200impl Expression for String {
201 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
202 writer.write_string(context, out, self);
203 }
204}
205
206impl OpPrecedence for Cow<'static, str> {
207 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
208 0
209 }
210}
211impl Expression for Cow<'static, str> {
212 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
213 writer.write_string(context, out, self.as_ref());
214 }
215}
216
217impl OpPrecedence for Box<[u8]> {
218 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
219 0
220 }
221}
222impl Expression for Box<[u8]> {
223 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
224 writer.write_value(context, out, &Value::Blob(Some(self.clone())));
225 }
226}
227
228impl OpPrecedence for serde_json::Value {
229 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
230 0
231 }
232}
233impl Expression for serde_json::Value {
234 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
235 writer.write_value(context, out, &Value::Json(Some(self.clone())));
236 }
237}
238
239impl<const W: u8, const S: u8> OpPrecedence for FixedDecimal<W, S> {
240 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
241 0
242 }
243}
244impl<const W: u8, const S: u8> Expression for FixedDecimal<W, S> {
245 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
246 writer.write_value(context, out, &(*self).as_value());
247 }
248}
249
250impl<T: Expression> OpPrecedence for Arc<T> {
251 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
252 0
253 }
254}
255impl<T: Expression> Expression for Arc<T> {
256 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
257 (**self).write_query(writer, context, out);
258 }
259 fn accept_visitor(
260 &self,
261 matcher: &mut dyn ExpressionVisitor,
262 writer: &dyn SqlWriter,
263 context: &mut Context,
264 out: &mut DynQuery,
265 ) -> bool {
266 (**self).accept_visitor(matcher, writer, context, out)
267 }
268}
269
270impl<T: Expression> OpPrecedence for Box<T> {
271 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
272 0
273 }
274}
275impl<T: Expression> Expression for Box<T> {
276 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
277 (**self).write_query(writer, context, out);
278 }
279 fn accept_visitor(
280 &self,
281 matcher: &mut dyn ExpressionVisitor,
282 writer: &dyn SqlWriter,
283 context: &mut Context,
284 out: &mut DynQuery,
285 ) -> bool {
286 (**self).accept_visitor(matcher, writer, context, out)
287 }
288}
289
290impl<T: AsValue + Expression> OpPrecedence for Option<T> {
291 fn precedence(&self, _: &dyn SqlWriter) -> i32 {
292 0
293 }
294}
295impl<T: AsValue + Expression> Expression for Option<T> {
296 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
297 match self {
298 Some(v) => v.write_query(writer, context, out),
299 None => writer.write_value(context, out, &T::as_empty_value()),
300 }
301 }
302}