Skip to main content

drizzle_core/expr/
primitives.rs

1//! Expr implementations for Rust primitive types.
2//!
3//! These implementations allow using Rust literals directly in type-safe
4//! SQL expressions.
5
6use crate::dialect::DialectTypes;
7use crate::prelude::*;
8use crate::sql::SQL;
9use crate::traits::{SQLBytes, SQLParam};
10
11use super::{Expr, NonNull, Null, Nullability, Scalar};
12
13// =============================================================================
14// Integer Types
15// =============================================================================
16
17impl<'a, V> Expr<'a, V> for i8
18where
19    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
20{
21    type SQLType = <V::DialectMarker as DialectTypes>::SmallInt;
22    type Nullable = NonNull;
23    type Aggregate = Scalar;
24}
25
26impl<'a, V> Expr<'a, V> for i16
27where
28    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
29{
30    type SQLType = <V::DialectMarker as DialectTypes>::SmallInt;
31    type Nullable = NonNull;
32    type Aggregate = Scalar;
33}
34
35impl<'a, V> Expr<'a, V> for i32
36where
37    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
38{
39    type SQLType = <V::DialectMarker as DialectTypes>::Int;
40    type Nullable = NonNull;
41    type Aggregate = Scalar;
42}
43
44impl<'a, V> Expr<'a, V> for i64
45where
46    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
47{
48    type SQLType = <V::DialectMarker as DialectTypes>::BigInt;
49    type Nullable = NonNull;
50    type Aggregate = Scalar;
51}
52
53impl<'a, V> Expr<'a, V> for isize
54where
55    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
56{
57    type SQLType = <V::DialectMarker as DialectTypes>::BigInt;
58    type Nullable = NonNull;
59    type Aggregate = Scalar;
60}
61
62// =============================================================================
63// Unsigned Integer Types
64// =============================================================================
65
66impl<'a, V> Expr<'a, V> for u8
67where
68    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
69{
70    type SQLType = <V::DialectMarker as DialectTypes>::SmallInt;
71    type Nullable = NonNull;
72    type Aggregate = Scalar;
73}
74
75impl<'a, V> Expr<'a, V> for u16
76where
77    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
78{
79    type SQLType = <V::DialectMarker as DialectTypes>::Int;
80    type Nullable = NonNull;
81    type Aggregate = Scalar;
82}
83
84impl<'a, V> Expr<'a, V> for u32
85where
86    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
87{
88    type SQLType = <V::DialectMarker as DialectTypes>::BigInt;
89    type Nullable = NonNull;
90    type Aggregate = Scalar;
91}
92
93impl<'a, V> Expr<'a, V> for u64
94where
95    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
96{
97    type SQLType = <V::DialectMarker as DialectTypes>::BigInt;
98    type Nullable = NonNull;
99    type Aggregate = Scalar;
100}
101
102impl<'a, V> Expr<'a, V> for usize
103where
104    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
105{
106    type SQLType = <V::DialectMarker as DialectTypes>::BigInt;
107    type Nullable = NonNull;
108    type Aggregate = Scalar;
109}
110
111// =============================================================================
112// Floating-Point Types
113// =============================================================================
114
115impl<'a, V> Expr<'a, V> for f32
116where
117    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
118{
119    type SQLType = <V::DialectMarker as DialectTypes>::Float;
120    type Nullable = NonNull;
121    type Aggregate = Scalar;
122}
123
124impl<'a, V> Expr<'a, V> for f64
125where
126    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
127{
128    type SQLType = <V::DialectMarker as DialectTypes>::Double;
129    type Nullable = NonNull;
130    type Aggregate = Scalar;
131}
132
133// =============================================================================
134// Boolean Type
135// =============================================================================
136
137impl<'a, V> Expr<'a, V> for bool
138where
139    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
140{
141    type SQLType = <V::DialectMarker as DialectTypes>::Bool;
142    type Nullable = NonNull;
143    type Aggregate = Scalar;
144}
145
146// =============================================================================
147// String Types
148// =============================================================================
149
150impl<'a, V> Expr<'a, V> for &'a str
151where
152    V: SQLParam + 'a + From<&'a str> + Into<Cow<'a, V>>,
153{
154    type SQLType = <V::DialectMarker as DialectTypes>::Text;
155    type Nullable = NonNull;
156    type Aggregate = Scalar;
157}
158
159impl<'a, V> Expr<'a, V> for String
160where
161    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
162{
163    type SQLType = <V::DialectMarker as DialectTypes>::Text;
164    type Nullable = NonNull;
165    type Aggregate = Scalar;
166}
167
168// =============================================================================
169// Binary Types
170// =============================================================================
171
172impl<'a, V> Expr<'a, V> for &'a [u8]
173where
174    V: SQLParam + 'a + From<&'a [u8]> + From<Vec<u8>> + From<u8> + Into<Cow<'a, V>>,
175{
176    type SQLType = <V::DialectMarker as DialectTypes>::Bytes;
177    type Nullable = NonNull;
178    type Aggregate = Scalar;
179
180    fn to_expr_sql(&self) -> SQL<'a, V> {
181        SQL::bytes(*self)
182    }
183
184    fn into_expr_sql(self) -> SQL<'a, V> {
185        SQL::bytes(self)
186    }
187}
188
189impl<'a, V, const N: usize> Expr<'a, V> for [u8; N]
190where
191    V: SQLParam + 'a + From<&'a [u8]> + From<Vec<u8>> + From<u8> + Into<Cow<'a, V>>,
192{
193    type SQLType = <V::DialectMarker as DialectTypes>::Bytes;
194    type Nullable = NonNull;
195    type Aggregate = Scalar;
196
197    fn to_expr_sql(&self) -> SQL<'a, V> {
198        SQL::bytes(self.to_vec())
199    }
200
201    fn into_expr_sql(self) -> SQL<'a, V> {
202        SQL::bytes(self.to_vec())
203    }
204}
205
206impl<'a, V> Expr<'a, V> for Vec<u8>
207where
208    V: SQLParam + 'a + From<&'a [u8]> + From<Vec<u8>> + From<u8> + Into<Cow<'a, V>>,
209{
210    type SQLType = <V::DialectMarker as DialectTypes>::Bytes;
211    type Nullable = NonNull;
212    type Aggregate = Scalar;
213
214    fn to_expr_sql(&self) -> SQL<'a, V> {
215        SQL::bytes(self.clone())
216    }
217
218    fn into_expr_sql(self) -> SQL<'a, V> {
219        SQL::bytes(self)
220    }
221}
222
223impl<'a, V> Expr<'a, V> for Cow<'a, [u8]>
224where
225    V: SQLParam + 'a + From<&'a [u8]> + From<Vec<u8>> + Into<Cow<'a, V>>,
226{
227    type SQLType = <V::DialectMarker as DialectTypes>::Bytes;
228    type Nullable = NonNull;
229    type Aggregate = Scalar;
230
231    fn to_expr_sql(&self) -> SQL<'a, V> {
232        match self {
233            Cow::Borrowed(value) => SQL::bytes(*value),
234            Cow::Owned(value) => SQL::bytes(value.clone()),
235        }
236    }
237
238    fn into_expr_sql(self) -> SQL<'a, V> {
239        SQL::bytes(self)
240    }
241}
242
243impl<'a, V> Expr<'a, V> for SQLBytes<'a>
244where
245    V: SQLParam + 'a + From<&'a [u8]> + From<Vec<u8>> + Into<Cow<'a, V>>,
246{
247    type SQLType = <V::DialectMarker as DialectTypes>::Bytes;
248    type Nullable = NonNull;
249    type Aggregate = Scalar;
250
251    fn to_expr_sql(&self) -> SQL<'a, V> {
252        match &self.0 {
253            Cow::Borrowed(value) => SQL::bytes(*value),
254            Cow::Owned(value) => SQL::bytes(value.clone()),
255        }
256    }
257
258    fn into_expr_sql(self) -> SQL<'a, V> {
259        SQL::bytes(self.0)
260    }
261}
262
263// =============================================================================
264// Option<T> - Makes Any Expression Nullable
265// =============================================================================
266
267impl<'a, V, T> Expr<'a, V> for Option<T>
268where
269    V: SQLParam + 'a,
270    T: Expr<'a, V>,
271    T::Nullable: Nullability,
272{
273    type SQLType = T::SQLType;
274    type Nullable = Null;
275    type Aggregate = T::Aggregate;
276}
277
278// =============================================================================
279// Reference Types - Delegate to Inner
280// =============================================================================
281
282impl<'a, V, T> Expr<'a, V> for &T
283where
284    V: SQLParam + 'a,
285    T: Expr<'a, V>,
286    T::Nullable: Nullability,
287{
288    type SQLType = T::SQLType;
289    type Nullable = T::Nullable;
290    type Aggregate = T::Aggregate;
291
292    fn to_expr_sql(&self) -> SQL<'a, V> {
293        (**self).to_expr_sql()
294    }
295
296    fn into_expr_sql(self) -> SQL<'a, V> {
297        (*self).to_expr_sql()
298    }
299}
300
301// =============================================================================
302// UUID (Feature-Gated)
303// =============================================================================
304
305#[cfg(feature = "uuid")]
306impl<'a, V> Expr<'a, V> for uuid::Uuid
307where
308    V: SQLParam + 'a + From<Self> + Into<Cow<'a, V>>,
309{
310    type SQLType = <V::DialectMarker as DialectTypes>::Uuid;
311    type Nullable = NonNull;
312    type Aggregate = Scalar;
313}
314
315// =============================================================================
316// SQL Type - Backward Compatibility
317// Allows untyped columns (which return SQL) to work with typed functions.
318// =============================================================================
319
320impl<'a, V> Expr<'a, V> for crate::sql::SQL<'a, V>
321where
322    V: SQLParam + 'a,
323{
324    type SQLType = <V::DialectMarker as DialectTypes>::Any;
325    type Nullable = Null;
326    type Aggregate = Scalar;
327}