1use core::marker::PhantomData;
8
9mod coerce;
10mod ops;
11
12pub use coerce::*;
13pub use ops::*;
14
15mod private {
16 pub trait Sealed {}
17}
18
19#[diagnostic::on_unimplemented(
21 message = "`{Self}` is not a recognized SQL data type",
22 label = "use a drizzle SQL type marker (Int, Text, Bool, etc.)"
23)]
24pub trait DataType: private::Sealed + Copy + 'static {}
25
26#[diagnostic::on_unimplemented(
28 message = "`{Self}` is not a numeric SQL type",
29 label = "arithmetic operations require Int, SmallInt, BigInt, Float, or Double"
30)]
31pub trait Numeric: DataType {}
32
33#[diagnostic::on_unimplemented(
35 message = "`{Self}` is not an integer SQL type",
36 label = "expected SmallInt, Int, or BigInt"
37)]
38pub trait Integral: Numeric {}
39
40#[diagnostic::on_unimplemented(
42 message = "`{Self}` is not a floating-point SQL type",
43 label = "expected Float or Double"
44)]
45pub trait Floating: Numeric {}
46
47#[diagnostic::on_unimplemented(
49 message = "`{Self}` is not a text SQL type",
50 label = "expected Text or VarChar"
51)]
52pub trait Textual: DataType {}
53
54#[diagnostic::on_unimplemented(
56 message = "`{Self}` is not a binary SQL type",
57 label = "expected Bytes (BLOB/BYTEA)"
58)]
59pub trait Binary: DataType {}
60
61#[diagnostic::on_unimplemented(
63 message = "`{Self}` is not a temporal SQL type",
64 label = "expected Date, Time, Timestamp, or TimestampTz"
65)]
66pub trait Temporal: DataType {}
67
68#[diagnostic::on_unimplemented(
70 message = "`{Self}` is not a boolean SQL type",
71 label = "logical operations require a boolean-typed expression"
72)]
73pub trait BooleanLike: DataType {}
74
75#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
79pub struct Array<T: DataType>(pub PhantomData<T>);
80
81#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
83pub struct Placeholder;
84
85#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
93pub struct Conjunction;
94
95impl<T: DataType> private::Sealed for Array<T> {}
96impl<T: DataType> DataType for Array<T> {}
97impl private::Sealed for Placeholder {}
98impl DataType for Placeholder {}
99impl Textual for Placeholder {}
100impl private::Sealed for Conjunction {}
101impl DataType for Conjunction {}
102impl BooleanLike for Conjunction {}
103
104impl private::Sealed for crate::sqlite::types::Integer {}
109impl private::Sealed for crate::sqlite::types::Text {}
110impl private::Sealed for crate::sqlite::types::Real {}
111impl private::Sealed for crate::sqlite::types::Blob {}
112impl private::Sealed for crate::sqlite::types::Numeric {}
113impl private::Sealed for crate::sqlite::types::Any {}
114
115impl DataType for crate::sqlite::types::Integer {}
116impl DataType for crate::sqlite::types::Text {}
117impl DataType for crate::sqlite::types::Real {}
118impl DataType for crate::sqlite::types::Blob {}
119impl DataType for crate::sqlite::types::Numeric {}
120impl DataType for crate::sqlite::types::Any {}
121
122impl Numeric for crate::sqlite::types::Integer {}
123impl Numeric for crate::sqlite::types::Real {}
124impl Numeric for crate::sqlite::types::Numeric {}
125impl Numeric for crate::sqlite::types::Any {}
126
127impl Integral for crate::sqlite::types::Integer {}
128
129impl Floating for crate::sqlite::types::Real {}
130
131impl Textual for crate::sqlite::types::Text {}
132impl Textual for crate::sqlite::types::Any {}
133
134impl Binary for crate::sqlite::types::Blob {}
135
136impl Temporal for crate::sqlite::types::Integer {}
137impl Temporal for crate::sqlite::types::Real {}
138impl Temporal for crate::sqlite::types::Text {}
139impl Temporal for crate::sqlite::types::Numeric {}
140
141impl BooleanLike for crate::sqlite::types::Integer {}
142
143impl private::Sealed for crate::postgres::types::Int2 {}
148impl private::Sealed for crate::postgres::types::Int4 {}
149impl private::Sealed for crate::postgres::types::Int8 {}
150impl private::Sealed for crate::postgres::types::Float4 {}
151impl private::Sealed for crate::postgres::types::Float8 {}
152impl private::Sealed for crate::postgres::types::Varchar {}
153impl private::Sealed for crate::postgres::types::Text {}
154impl private::Sealed for crate::postgres::types::Char {}
155impl private::Sealed for crate::postgres::types::Bytea {}
156impl private::Sealed for crate::postgres::types::Boolean {}
157impl private::Sealed for crate::postgres::types::Timestamptz {}
158impl private::Sealed for crate::postgres::types::Timestamp {}
159impl private::Sealed for crate::postgres::types::Date {}
160impl private::Sealed for crate::postgres::types::Time {}
161impl private::Sealed for crate::postgres::types::Timetz {}
162impl private::Sealed for crate::postgres::types::Numeric {}
163impl private::Sealed for crate::postgres::types::Uuid {}
164impl private::Sealed for crate::postgres::types::Json {}
165impl private::Sealed for crate::postgres::types::Jsonb {}
166impl private::Sealed for crate::postgres::types::Any {}
167impl private::Sealed for crate::postgres::types::Interval {}
168impl private::Sealed for crate::postgres::types::Inet {}
169impl private::Sealed for crate::postgres::types::Cidr {}
170impl private::Sealed for crate::postgres::types::MacAddr {}
171impl private::Sealed for crate::postgres::types::MacAddr8 {}
172impl private::Sealed for crate::postgres::types::Point {}
173impl private::Sealed for crate::postgres::types::LineString {}
174impl private::Sealed for crate::postgres::types::Rect {}
175impl private::Sealed for crate::postgres::types::BitString {}
176impl private::Sealed for crate::postgres::types::Line {}
177impl private::Sealed for crate::postgres::types::LineSegment {}
178impl private::Sealed for crate::postgres::types::Polygon {}
179impl private::Sealed for crate::postgres::types::Circle {}
180impl private::Sealed for crate::postgres::types::Enum {}
181
182impl DataType for crate::postgres::types::Int2 {}
183impl DataType for crate::postgres::types::Int4 {}
184impl DataType for crate::postgres::types::Int8 {}
185impl DataType for crate::postgres::types::Float4 {}
186impl DataType for crate::postgres::types::Float8 {}
187impl DataType for crate::postgres::types::Varchar {}
188impl DataType for crate::postgres::types::Text {}
189impl DataType for crate::postgres::types::Char {}
190impl DataType for crate::postgres::types::Bytea {}
191impl DataType for crate::postgres::types::Boolean {}
192impl DataType for crate::postgres::types::Timestamptz {}
193impl DataType for crate::postgres::types::Timestamp {}
194impl DataType for crate::postgres::types::Date {}
195impl DataType for crate::postgres::types::Time {}
196impl DataType for crate::postgres::types::Timetz {}
197impl DataType for crate::postgres::types::Numeric {}
198impl DataType for crate::postgres::types::Uuid {}
199impl DataType for crate::postgres::types::Json {}
200impl DataType for crate::postgres::types::Jsonb {}
201impl DataType for crate::postgres::types::Any {}
202impl DataType for crate::postgres::types::Interval {}
203impl DataType for crate::postgres::types::Inet {}
204impl DataType for crate::postgres::types::Cidr {}
205impl DataType for crate::postgres::types::MacAddr {}
206impl DataType for crate::postgres::types::MacAddr8 {}
207impl DataType for crate::postgres::types::Point {}
208impl DataType for crate::postgres::types::LineString {}
209impl DataType for crate::postgres::types::Rect {}
210impl DataType for crate::postgres::types::BitString {}
211impl DataType for crate::postgres::types::Line {}
212impl DataType for crate::postgres::types::LineSegment {}
213impl DataType for crate::postgres::types::Polygon {}
214impl DataType for crate::postgres::types::Circle {}
215impl DataType for crate::postgres::types::Enum {}
216
217impl Numeric for crate::postgres::types::Int2 {}
218impl Numeric for crate::postgres::types::Int4 {}
219impl Numeric for crate::postgres::types::Int8 {}
220impl Numeric for crate::postgres::types::Float4 {}
221impl Numeric for crate::postgres::types::Float8 {}
222impl Numeric for crate::postgres::types::Numeric {}
223
224impl Integral for crate::postgres::types::Int2 {}
225impl Integral for crate::postgres::types::Int4 {}
226impl Integral for crate::postgres::types::Int8 {}
227
228impl Floating for crate::postgres::types::Float4 {}
229impl Floating for crate::postgres::types::Float8 {}
230
231impl Textual for crate::postgres::types::Varchar {}
232impl Textual for crate::postgres::types::Text {}
233impl Textual for crate::postgres::types::Char {}
234impl Textual for crate::postgres::types::Enum {}
235
236impl Binary for crate::postgres::types::Bytea {}
237
238impl Temporal for crate::postgres::types::Timestamptz {}
239impl Temporal for crate::postgres::types::Timestamp {}
240impl Temporal for crate::postgres::types::Date {}
241impl Temporal for crate::postgres::types::Time {}
242impl Temporal for crate::postgres::types::Timetz {}
243
244impl Temporal for crate::postgres::types::Interval {}
245
246impl BooleanLike for crate::postgres::types::Boolean {}
247
248macro_rules! impl_mysql_data_types {
253 ($($marker:ident),+ $(,)?) => {
254 $(
255 impl private::Sealed for crate::mysql::types::$marker {}
256 impl DataType for crate::mysql::types::$marker {}
257 )+
258 };
259}
260
261impl_mysql_data_types!(
262 TinyInt,
263 TinyIntUnsigned,
264 SmallInt,
265 SmallIntUnsigned,
266 MediumInt,
267 MediumIntUnsigned,
268 Int,
269 IntUnsigned,
270 BigInt,
271 BigIntUnsigned,
272 Float,
273 Double,
274 Decimal,
275 Boolean,
276 Char,
277 Varchar,
278 TinyText,
279 Text,
280 MediumText,
281 LongText,
282 Binary,
283 Varbinary,
284 TinyBlob,
285 Blob,
286 MediumBlob,
287 LongBlob,
288 Json,
289 Date,
290 Time,
291 DateTime,
292 Timestamp,
293 Year,
294 Enum,
295 Set,
296 Bit,
297 Any,
298);
299
300macro_rules! impl_mysql_marker_trait {
301 ($trait:ident; $($marker:ident),+ $(,)?) => {
302 $(impl $trait for crate::mysql::types::$marker {})+
303 };
304}
305
306impl_mysql_marker_trait!(Numeric;
307 TinyInt,
308 TinyIntUnsigned,
309 SmallInt,
310 SmallIntUnsigned,
311 MediumInt,
312 MediumIntUnsigned,
313 Int,
314 IntUnsigned,
315 BigInt,
316 BigIntUnsigned,
317 Year,
318 Float,
319 Double,
320 Decimal,
321);
322
323impl_mysql_marker_trait!(Integral;
324 TinyInt,
325 TinyIntUnsigned,
326 SmallInt,
327 SmallIntUnsigned,
328 MediumInt,
329 MediumIntUnsigned,
330 Int,
331 IntUnsigned,
332 BigInt,
333 BigIntUnsigned,
334 Year,
335);
336
337impl Floating for crate::mysql::types::Float {}
338impl Floating for crate::mysql::types::Double {}
339
340impl_mysql_marker_trait!(Textual;
341 Char, Varchar, TinyText, Text, MediumText, LongText, Enum, Set,
342);
343
344impl_mysql_marker_trait!(Binary; Binary, Varbinary, TinyBlob, Blob, MediumBlob, LongBlob, Bit,);
345
346impl Temporal for crate::mysql::types::Date {}
347impl Temporal for crate::mysql::types::Time {}
348impl Temporal for crate::mysql::types::DateTime {}
349impl Temporal for crate::mysql::types::Timestamp {}
350
351impl BooleanLike for crate::mysql::types::Boolean {}
352
353macro_rules! seq_tuples {
358 (@acc $callback:ident [$($aT:ident),*] [$($ai:tt),*]) => {};
359 (@acc $callback:ident [$($aT:ident),*] [$($ai:tt),*] ($T:ident, $i:tt) $($rest:tt)*) => {
360 $callback!($($aT,)* $T; $($ai,)* $i);
361 seq_tuples!(@acc $callback [$($aT,)* $T] [$($ai,)* $i] $($rest)*);
362 };
363 ($callback:ident; $($pairs:tt)+) => {
364 seq_tuples!(@acc $callback [] [] $($pairs)+);
365 };
366 (@from $callback:ident [$($aT:ident),*] [$($ai:tt),*]; $($pairs:tt)+) => {
367 seq_tuples!(@acc $callback [$($aT),*] [$($ai),*] $($pairs)+);
368 };
369}
370
371macro_rules! with_col_sizes_8 {
372 ($callback:ident) => {
373 seq_tuples!($callback;
374 (T0,0) (T1,1) (T2,2) (T3,3)
375 (T4,4) (T5,5) (T6,6) (T7,7)
376 );
377 };
378}
379
380#[allow(unused_macros)]
381macro_rules! with_col_sizes_16 {
382 ($callback:ident) => {
383 seq_tuples!(@from $callback
384 [T0,T1,T2,T3,T4,T5,T6,T7]
385 [0,1,2,3,4,5,6,7];
386 (T8,8) (T9,9) (T10,10) (T11,11)
387 (T12,12) (T13,13) (T14,14) (T15,15)
388 );
389 };
390}
391
392#[allow(unused_macros)]
393macro_rules! with_col_sizes_32 {
394 ($callback:ident) => {
395 seq_tuples!(@from $callback
396 [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15]
397 [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
398 (T16,16) (T17,17) (T18,18) (T19,19)
399 (T20,20) (T21,21) (T22,22) (T23,23)
400 (T24,24) (T25,25) (T26,26) (T27,27)
401 (T28,28) (T29,29) (T30,30) (T31,31)
402 );
403 };
404}
405
406#[allow(unused_macros)]
407macro_rules! with_col_sizes_64 {
408 ($callback:ident) => {
409 seq_tuples!(@from $callback
410 [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
411 T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31]
412 [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
413 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
414 (T32,32) (T33,33) (T34,34) (T35,35)
415 (T36,36) (T37,37) (T38,38) (T39,39)
416 (T40,40) (T41,41) (T42,42) (T43,43)
417 (T44,44) (T45,45) (T46,46) (T47,47)
418 (T48,48) (T49,49) (T50,50) (T51,51)
419 (T52,52) (T53,53) (T54,54) (T55,55)
420 (T56,56) (T57,57) (T58,58) (T59,59)
421 (T60,60) (T61,61) (T62,62) (T63,63)
422 );
423 };
424}
425
426#[allow(unused_macros)]
427macro_rules! with_col_sizes_128 {
428 ($callback:ident) => {
429 seq_tuples!(@from $callback
430 [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
431 T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,
432 T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,
433 T48,T49,T50,T51,T52,T53,T54,T55,T56,T57,T58,T59,T60,T61,T62,T63]
434 [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
435 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
436 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
437 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63];
438 (T64,64) (T65,65) (T66,66) (T67,67)
439 (T68,68) (T69,69) (T70,70) (T71,71)
440 (T72,72) (T73,73) (T74,74) (T75,75)
441 (T76,76) (T77,77) (T78,78) (T79,79)
442 (T80,80) (T81,81) (T82,82) (T83,83)
443 (T84,84) (T85,85) (T86,86) (T87,87)
444 (T88,88) (T89,89) (T90,90) (T91,91)
445 (T92,92) (T93,93) (T94,94) (T95,95)
446 (T96,96) (T97,97) (T98,98) (T99,99)
447 (T100,100) (T101,101) (T102,102) (T103,103)
448 (T104,104) (T105,105) (T106,106) (T107,107)
449 (T108,108) (T109,109) (T110,110) (T111,111)
450 (T112,112) (T113,113) (T114,114) (T115,115)
451 (T116,116) (T117,117) (T118,118) (T119,119)
452 (T120,120) (T121,121) (T122,122) (T123,123)
453 (T124,124) (T125,125) (T126,126) (T127,127)
454 );
455 };
456}
457
458#[allow(unused_macros)]
459macro_rules! with_col_sizes_200 {
460 ($callback:ident) => {
461 seq_tuples!(@from $callback
462 [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
463 T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,
464 T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,
465 T48,T49,T50,T51,T52,T53,T54,T55,T56,T57,T58,T59,T60,T61,T62,T63,
466 T64,T65,T66,T67,T68,T69,T70,T71,T72,T73,T74,T75,T76,T77,T78,T79,
467 T80,T81,T82,T83,T84,T85,T86,T87,T88,T89,T90,T91,T92,T93,T94,T95,
468 T96,T97,T98,T99,T100,T101,T102,T103,T104,T105,T106,T107,T108,T109,T110,T111,
469 T112,T113,T114,T115,T116,T117,T118,T119,T120,T121,T122,T123,T124,T125,T126,T127]
470 [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
471 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
472 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
473 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
474 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
475 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
476 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
477 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127];
478 (T128,128) (T129,129) (T130,130) (T131,131)
479 (T132,132) (T133,133) (T134,134) (T135,135)
480 (T136,136) (T137,137) (T138,138) (T139,139)
481 (T140,140) (T141,141) (T142,142) (T143,143)
482 (T144,144) (T145,145) (T146,146) (T147,147)
483 (T148,148) (T149,149) (T150,150) (T151,151)
484 (T152,152) (T153,153) (T154,154) (T155,155)
485 (T156,156) (T157,157) (T158,158) (T159,159)
486 (T160,160) (T161,161) (T162,162) (T163,163)
487 (T164,164) (T165,165) (T166,166) (T167,167)
488 (T168,168) (T169,169) (T170,170) (T171,171)
489 (T172,172) (T173,173) (T174,174) (T175,175)
490 (T176,176) (T177,177) (T178,178) (T179,179)
491 (T180,180) (T181,181) (T182,182) (T183,183)
492 (T184,184) (T185,185) (T186,186) (T187,187)
493 (T188,188) (T189,189) (T190,190) (T191,191)
494 (T192,192) (T193,193) (T194,194) (T195,195)
495 (T196,196) (T197,197) (T198,198) (T199,199)
496 );
497 };
498}
499
500macro_rules! impl_tuple_datatype {
501 ($($T:ident),+; $($idx:tt),+) => {
502 impl<$($T: DataType),+> private::Sealed for ($($T,)+) {}
503 impl<$($T: DataType),+> DataType for ($($T,)+) {}
504 };
505}
506
507with_col_sizes_8!(impl_tuple_datatype);
508
509#[cfg(any(
510 feature = "col16",
511 feature = "col32",
512 feature = "col64",
513 feature = "col128",
514 feature = "col200"
515))]
516with_col_sizes_16!(impl_tuple_datatype);
517
518#[cfg(any(
519 feature = "col32",
520 feature = "col64",
521 feature = "col128",
522 feature = "col200"
523))]
524with_col_sizes_32!(impl_tuple_datatype);
525
526#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
527with_col_sizes_64!(impl_tuple_datatype);
528
529#[cfg(any(feature = "col128", feature = "col200"))]
530with_col_sizes_128!(impl_tuple_datatype);
531
532#[cfg(feature = "col200")]
533with_col_sizes_200!(impl_tuple_datatype);
534
535#[cfg(test)]
536mod tests {
537 use super::*;
538
539 fn assert_data_type<T: DataType>() {}
540 fn assert_integral<T: Integral>() {}
541 fn assert_floating<T: Floating>() {}
542 fn assert_textual<T: Textual>() {}
543 fn assert_binary<T: Binary>() {}
544 fn assert_temporal<T: Temporal>() {}
545 fn assert_boolean_like<T: BooleanLike>() {}
546
547 #[test]
548 fn mysql_markers_have_their_expected_type_capabilities() {
549 assert_data_type::<crate::mysql::types::Any>();
550 assert_integral::<crate::mysql::types::IntUnsigned>();
551 assert_integral::<crate::mysql::types::Year>();
552 assert_floating::<crate::mysql::types::Float>();
553 assert_floating::<crate::mysql::types::Double>();
554 assert_textual::<crate::mysql::types::Enum>();
555 assert_textual::<crate::mysql::types::Set>();
556 assert_binary::<crate::mysql::types::Varbinary>();
557 assert_binary::<crate::mysql::types::Bit>();
558 assert_temporal::<crate::mysql::types::DateTime>();
559 assert_boolean_like::<crate::mysql::types::Boolean>();
560 }
561}