1use crate::dialect::{MySQLDialect, PostgresDialect, SQLiteDialect};
2use crate::traits::SQLParam;
3use crate::types::{Assignable, DataType};
4
5#[cfg(any(feature = "alloc", feature = "std"))]
6use crate::prelude::{Arc, Box, Cow, Rc, String, Vec};
7
8pub trait ValueTypeForDialect<D> {
10 type SQLType: DataType;
11}
12
13pub trait BindValue<'a, V: SQLParam, Expected: DataType>: Sized {
15 fn into_bind_value(self) -> V;
16}
17
18pub trait NullableBindValue<'a, V: SQLParam, Expected: DataType>: Sized {
20 fn into_nullable_bind_value(self) -> V;
21}
22
23impl<V, Expected, T> BindValue<'_, V, Expected> for T
24where
25 V: SQLParam + From<T>,
26 Expected: DataType + Assignable<<T as ValueTypeForDialect<V::DialectMarker>>::SQLType>,
27 T: ValueTypeForDialect<V::DialectMarker>,
28{
29 fn into_bind_value(self) -> V {
30 V::from(self)
31 }
32}
33
34impl<V, Expected, T> NullableBindValue<'_, V, Expected> for Option<T>
35where
36 V: SQLParam + From<Self>,
37 Expected: DataType + Assignable<<T as ValueTypeForDialect<V::DialectMarker>>::SQLType>,
38 T: ValueTypeForDialect<V::DialectMarker>,
39{
40 fn into_nullable_bind_value(self) -> V {
41 V::from(self)
42 }
43}
44
45macro_rules! impl_value_type {
51 ($dialect:ty, $sql:ty => $($ty:ty),+ $(,)?) => {
52 $(
53 impl ValueTypeForDialect<$dialect> for $ty {
54 type SQLType = $sql;
55 }
56 )+
57 };
58}
59
60macro_rules! impl_value_type_const_n {
64 ($dialect:ty, $sql:ty => $($ty:ty),+ $(,)?) => {
65 $(
66 impl<const N: usize> ValueTypeForDialect<$dialect> for $ty {
67 type SQLType = $sql;
68 }
69 )+
70 };
71}
72
73use drizzle_types::sqlite::types as sqlite_ty;
78
79impl_value_type!(SQLiteDialect, sqlite_ty::Integer =>
80 i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, bool);
81
82impl_value_type!(SQLiteDialect, sqlite_ty::Real => f32, f64);
83
84impl_value_type!(SQLiteDialect, sqlite_ty::Text => &str);
85
86#[cfg(any(feature = "alloc", feature = "std"))]
87impl_value_type!(SQLiteDialect, sqlite_ty::Text =>
88 Cow<'_, str>,
89 String,
90 Box<String>,
91 Rc<String>,
92 Arc<String>,
93 Box<str>,
94 Rc<str>,
95 Arc<str>,
96);
97
98impl_value_type!(SQLiteDialect, sqlite_ty::Text => compact_str::CompactString);
99
100#[cfg(feature = "arrayvec")]
101impl_value_type_const_n!(SQLiteDialect, sqlite_ty::Text => arrayvec::ArrayString<N>);
102
103impl_value_type!(SQLiteDialect, sqlite_ty::Blob => &[u8]);
104
105#[cfg(any(feature = "alloc", feature = "std"))]
106impl_value_type!(SQLiteDialect, sqlite_ty::Blob =>
107 Cow<'_, [u8]>,
108 Vec<u8>,
109 Box<Vec<u8>>,
110 Rc<Vec<u8>>,
111 Arc<Vec<u8>>,
112);
113
114#[cfg(feature = "arrayvec")]
115impl_value_type_const_n!(SQLiteDialect, sqlite_ty::Blob => arrayvec::ArrayVec<u8, N>);
116
117#[cfg(feature = "bytes")]
118impl_value_type!(SQLiteDialect, sqlite_ty::Blob => bytes::Bytes, bytes::BytesMut);
119
120#[cfg(feature = "smallvec-types")]
121impl_value_type_const_n!(SQLiteDialect, sqlite_ty::Blob => smallvec::SmallVec<[u8; N]>);
122
123#[cfg(feature = "uuid")]
124impl_value_type!(SQLiteDialect, sqlite_ty::Blob => uuid::Uuid, &uuid::Uuid);
125
126#[cfg(feature = "chrono")]
127impl_value_type!(SQLiteDialect, sqlite_ty::Text =>
128 chrono::NaiveDate,
129 chrono::NaiveTime,
130 chrono::NaiveDateTime,
131 chrono::DateTime<chrono::FixedOffset>,
132 chrono::DateTime<chrono::Utc>,
133 chrono::Duration,
134);
135
136#[cfg(feature = "time")]
137impl_value_type!(SQLiteDialect, sqlite_ty::Text =>
138 time::Date,
139 time::Time,
140 time::PrimitiveDateTime,
141 time::OffsetDateTime,
142 time::Duration,
143);
144
145#[cfg(feature = "jiff")]
146impl_value_type!(SQLiteDialect, sqlite_ty::Text =>
147 jiff::civil::Date,
148 jiff::civil::Time,
149 jiff::civil::DateTime,
150 jiff::Timestamp,
151);
152
153#[cfg(feature = "rust-decimal")]
154impl_value_type!(SQLiteDialect, sqlite_ty::Text =>
155 rust_decimal::Decimal,
156 &rust_decimal::Decimal,
157);
158
159#[cfg(feature = "serde")]
160impl_value_type!(SQLiteDialect, sqlite_ty::Text => serde_json::Value);
161
162use drizzle_types::postgres::types as pg_ty;
167
168impl_value_type!(PostgresDialect, pg_ty::Int2 => i8, i16, u8);
169impl_value_type!(PostgresDialect, pg_ty::Int4 => i32, u16);
170impl_value_type!(PostgresDialect, pg_ty::Int8 => i64, u32, u64, isize, usize);
171impl_value_type!(PostgresDialect, pg_ty::Float4 => f32);
172impl_value_type!(PostgresDialect, pg_ty::Float8 => f64);
173impl_value_type!(PostgresDialect, pg_ty::Boolean => bool);
174
175impl_value_type!(PostgresDialect, pg_ty::Text => &str);
176
177#[cfg(any(feature = "alloc", feature = "std"))]
178impl_value_type!(PostgresDialect, pg_ty::Text =>
179 Cow<'_, str>,
180 String,
181 Box<String>,
182 Rc<String>,
183 Arc<String>,
184 Box<str>,
185 Rc<str>,
186 Arc<str>,
187);
188
189#[cfg(feature = "compact-str")]
190impl_value_type!(PostgresDialect, pg_ty::Text => compact_str::CompactString);
191
192#[cfg(feature = "arrayvec")]
193impl_value_type_const_n!(PostgresDialect, pg_ty::Text => arrayvec::ArrayString<N>);
194
195impl_value_type!(PostgresDialect, pg_ty::Bytea => &[u8]);
196
197#[cfg(any(feature = "alloc", feature = "std"))]
198impl_value_type!(PostgresDialect, pg_ty::Bytea =>
199 Cow<'_, [u8]>,
200 Vec<u8>,
201 Box<Vec<u8>>,
202 Rc<Vec<u8>>,
203 Arc<Vec<u8>>,
204);
205
206#[cfg(feature = "arrayvec")]
207impl_value_type_const_n!(PostgresDialect, pg_ty::Bytea => arrayvec::ArrayVec<u8, N>);
208
209#[cfg(feature = "bytes")]
210impl_value_type!(PostgresDialect, pg_ty::Bytea => bytes::Bytes, bytes::BytesMut);
211
212#[cfg(feature = "smallvec-types")]
213impl_value_type_const_n!(PostgresDialect, pg_ty::Bytea => smallvec::SmallVec<[u8; N]>);
214
215#[cfg(feature = "uuid")]
216impl_value_type!(PostgresDialect, pg_ty::Uuid => uuid::Uuid, &uuid::Uuid);
217
218#[cfg(feature = "rust-decimal")]
219impl_value_type!(PostgresDialect, pg_ty::Numeric =>
220 rust_decimal::Decimal,
221 &rust_decimal::Decimal,
222);
223
224#[cfg(feature = "serde")]
225impl_value_type!(PostgresDialect, pg_ty::Json => serde_json::Value);
226
227#[cfg(feature = "chrono")]
228impl_value_type!(PostgresDialect, pg_ty::Date => chrono::NaiveDate);
229#[cfg(feature = "chrono")]
230impl_value_type!(PostgresDialect, pg_ty::Time => chrono::NaiveTime);
231#[cfg(feature = "chrono")]
232impl_value_type!(PostgresDialect, pg_ty::Timestamp => chrono::NaiveDateTime);
233#[cfg(feature = "chrono")]
234impl_value_type!(PostgresDialect, pg_ty::Timestamptz =>
235 chrono::DateTime<chrono::FixedOffset>,
236 chrono::DateTime<chrono::Utc>,
237);
238#[cfg(feature = "chrono")]
239impl_value_type!(PostgresDialect, pg_ty::Interval => chrono::Duration);
240
241#[cfg(feature = "time")]
242impl_value_type!(PostgresDialect, pg_ty::Date => time::Date);
243#[cfg(feature = "time")]
244impl_value_type!(PostgresDialect, pg_ty::Time => time::Time);
245#[cfg(feature = "time")]
246impl_value_type!(PostgresDialect, pg_ty::Timestamp => time::PrimitiveDateTime);
247#[cfg(feature = "time")]
248impl_value_type!(PostgresDialect, pg_ty::Timestamptz => time::OffsetDateTime);
249#[cfg(feature = "time")]
250impl_value_type!(PostgresDialect, pg_ty::Interval => time::Duration);
251
252#[cfg(feature = "jiff")]
253impl_value_type!(PostgresDialect, pg_ty::Date => jiff::civil::Date);
254#[cfg(feature = "jiff")]
255impl_value_type!(PostgresDialect, pg_ty::Time => jiff::civil::Time);
256#[cfg(feature = "jiff")]
257impl_value_type!(PostgresDialect, pg_ty::Timestamp => jiff::civil::DateTime);
258#[cfg(feature = "jiff")]
259impl_value_type!(PostgresDialect, pg_ty::Timestamptz => jiff::Timestamp);
260
261#[cfg(feature = "cidr")]
262impl_value_type!(PostgresDialect, pg_ty::Inet => cidr::IpInet);
263#[cfg(feature = "cidr")]
264impl_value_type!(PostgresDialect, pg_ty::Cidr => cidr::IpCidr);
265#[cfg(feature = "cidr")]
266impl_value_type!(PostgresDialect, pg_ty::MacAddr => [u8; 6]);
267#[cfg(feature = "cidr")]
268impl_value_type!(PostgresDialect, pg_ty::MacAddr8 => [u8; 8]);
269
270#[cfg(feature = "geo-types")]
271impl_value_type!(PostgresDialect, pg_ty::Point => geo_types::Point<f64>);
272#[cfg(feature = "geo-types")]
273impl_value_type!(PostgresDialect, pg_ty::LineString => geo_types::LineString<f64>);
274#[cfg(feature = "geo-types")]
275impl_value_type!(PostgresDialect, pg_ty::Rect => geo_types::Rect<f64>);
276
277#[cfg(feature = "bit-vec")]
278impl_value_type!(PostgresDialect, pg_ty::BitString => bit_vec::BitVec);
279
280#[cfg(any(feature = "alloc", feature = "std"))]
283impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Text> =>
284 Vec<String>, Vec<&str>);
285
286#[cfg(any(feature = "alloc", feature = "std"))]
287impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Int2> => Vec<i16>);
288
289#[cfg(any(feature = "alloc", feature = "std"))]
290impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Int4> => Vec<i32>);
291
292#[cfg(any(feature = "alloc", feature = "std"))]
293impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Int8> => Vec<i64>);
294
295#[cfg(any(feature = "alloc", feature = "std"))]
296impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Float4> => Vec<f32>);
297
298#[cfg(any(feature = "alloc", feature = "std"))]
299impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Float8> => Vec<f64>);
300
301#[cfg(any(feature = "alloc", feature = "std"))]
302impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Boolean> => Vec<bool>);
303
304#[cfg(all(any(feature = "alloc", feature = "std"), feature = "uuid"))]
305impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Uuid> => Vec<uuid::Uuid>);
306
307#[cfg(all(any(feature = "alloc", feature = "std"), feature = "chrono"))]
308impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Date> => Vec<chrono::NaiveDate>);
309
310#[cfg(all(any(feature = "alloc", feature = "std"), feature = "chrono"))]
311impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Time> => Vec<chrono::NaiveTime>);
312
313#[cfg(all(any(feature = "alloc", feature = "std"), feature = "chrono"))]
314impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Timestamp> => Vec<chrono::NaiveDateTime>);
315
316#[cfg(all(any(feature = "alloc", feature = "std"), feature = "chrono"))]
317impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Timestamptz> => Vec<chrono::DateTime<chrono::Utc>>);
318
319#[cfg(all(any(feature = "alloc", feature = "std"), feature = "rust-decimal"))]
320impl_value_type!(PostgresDialect, drizzle_types::Array<pg_ty::Numeric> => Vec<rust_decimal::Decimal>);
321
322use drizzle_types::mysql::types as mysql_ty;
327
328impl_value_type!(MySQLDialect, mysql_ty::TinyInt => i8);
329impl_value_type!(MySQLDialect, mysql_ty::SmallInt => i16);
330impl_value_type!(MySQLDialect, mysql_ty::Int => i32);
331impl_value_type!(MySQLDialect, mysql_ty::BigInt => i64, isize);
332impl_value_type!(MySQLDialect, mysql_ty::TinyIntUnsigned => u8);
333impl_value_type!(MySQLDialect, mysql_ty::SmallIntUnsigned => u16);
334impl_value_type!(MySQLDialect, mysql_ty::IntUnsigned => u32);
335impl_value_type!(MySQLDialect, mysql_ty::BigIntUnsigned => u64, usize);
336impl_value_type!(MySQLDialect, mysql_ty::Float => f32);
337impl_value_type!(MySQLDialect, mysql_ty::Double => f64);
338impl_value_type!(MySQLDialect, mysql_ty::Boolean => bool);
339
340impl_value_type!(MySQLDialect, mysql_ty::Text => &str);
341
342#[cfg(any(feature = "alloc", feature = "std"))]
343impl_value_type!(MySQLDialect, mysql_ty::Text =>
344 Cow<'_, str>,
345 String,
346 Box<String>,
347 Rc<String>,
348 Arc<String>,
349 Box<str>,
350 Rc<str>,
351 Arc<str>,
352);
353
354#[cfg(feature = "compact-str")]
355impl_value_type!(MySQLDialect, mysql_ty::Text => compact_str::CompactString);
356
357#[cfg(feature = "arrayvec")]
358impl_value_type_const_n!(MySQLDialect, mysql_ty::Varchar => arrayvec::ArrayString<N>);
359
360impl_value_type!(MySQLDialect, mysql_ty::Blob => &[u8]);
361
362#[cfg(any(feature = "alloc", feature = "std"))]
363impl_value_type!(MySQLDialect, mysql_ty::Blob =>
364 Cow<'_, [u8]>,
365 Vec<u8>,
366 Box<Vec<u8>>,
367 Rc<Vec<u8>>,
368 Arc<Vec<u8>>,
369);
370
371#[cfg(feature = "arrayvec")]
372impl_value_type_const_n!(MySQLDialect, mysql_ty::Varbinary => arrayvec::ArrayVec<u8, N>);
373
374impl_value_type_const_n!(MySQLDialect, mysql_ty::Binary => [u8; N]);
375impl_value_type_const_n!(MySQLDialect, mysql_ty::Char => [char; N]);
376
377#[cfg(feature = "bytes")]
378impl_value_type!(MySQLDialect, mysql_ty::Blob => bytes::Bytes, bytes::BytesMut);
379
380#[cfg(feature = "smallvec-types")]
381impl_value_type_const_n!(MySQLDialect, mysql_ty::Blob => smallvec::SmallVec<[u8; N]>);
382
383#[cfg(feature = "uuid")]
384impl_value_type!(MySQLDialect, mysql_ty::Binary => uuid::Uuid, &uuid::Uuid);
385
386#[cfg(feature = "rust-decimal")]
387impl_value_type!(MySQLDialect, mysql_ty::Decimal =>
388 rust_decimal::Decimal,
389 &rust_decimal::Decimal,
390);
391
392#[cfg(feature = "serde")]
393impl_value_type!(MySQLDialect, mysql_ty::Json => serde_json::Value);
394
395#[cfg(feature = "chrono")]
396impl_value_type!(MySQLDialect, mysql_ty::Date => chrono::NaiveDate);
397#[cfg(feature = "chrono")]
398impl_value_type!(MySQLDialect, mysql_ty::Time => chrono::NaiveTime);
399#[cfg(feature = "chrono")]
400impl_value_type!(MySQLDialect, mysql_ty::DateTime => chrono::NaiveDateTime);
401#[cfg(feature = "chrono")]
402impl_value_type!(MySQLDialect, mysql_ty::Timestamp =>
403 chrono::DateTime<chrono::FixedOffset>,
404 chrono::DateTime<chrono::Utc>,
405);
406
407#[cfg(feature = "time")]
408impl_value_type!(MySQLDialect, mysql_ty::Date => time::Date);
409#[cfg(feature = "time")]
410impl_value_type!(MySQLDialect, mysql_ty::Time => time::Time);
411#[cfg(feature = "time")]
412impl_value_type!(MySQLDialect, mysql_ty::DateTime => time::PrimitiveDateTime);
413#[cfg(feature = "time")]
414impl_value_type!(MySQLDialect, mysql_ty::Timestamp => time::OffsetDateTime);
415
416#[cfg(feature = "jiff")]
417impl_value_type!(MySQLDialect, mysql_ty::Date => jiff::civil::Date);
418#[cfg(feature = "jiff")]
419impl_value_type!(MySQLDialect, mysql_ty::Time => jiff::civil::Time);
420#[cfg(feature = "jiff")]
421impl_value_type!(MySQLDialect, mysql_ty::DateTime => jiff::civil::DateTime);
422#[cfg(feature = "jiff")]
423impl_value_type!(MySQLDialect, mysql_ty::Timestamp => jiff::Timestamp);