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