use super::DataType;
#[diagnostic::on_unimplemented(
message = "SQL type `{Self}` is not compatible with `{Rhs}`",
label = "these SQL types cannot be compared or coerced",
note = "compatible types include: integers with integers/floats, text with text/varchar, and any type with itself"
)]
pub trait Compatible<Rhs: DataType = Self>: DataType {}
#[diagnostic::on_unimplemented(
message = "SQL type `{Self}` is not assignable from `{Rhs}`",
label = "this value type cannot be bound to the placeholder/column type",
note = "assignment is stricter than comparison compatibility; use a value matching the target SQL marker"
)]
pub trait Assignable<Rhs: DataType = Self>: DataType {}
macro_rules! impl_reflexive_compat {
($($ty:ty),+ $(,)?) => {
$(impl Compatible<$ty> for $ty {})+
};
}
macro_rules! impl_reflexive_assign {
($($ty:ty),+ $(,)?) => {
$(impl Assignable<$ty> for $ty {})+
};
}
macro_rules! mutual_compat {
($($ty:ty),+ $(,)?) => {
mutual_compat!(@pairs [] $($ty),+);
};
(@pairs [$($done:ty),*]) => {};
(@pairs [$($done:ty),*] $first:ty $(, $rest:ty)*) => {
$(
impl Compatible<$rest> for $first {}
impl Compatible<$first> for $rest {}
)*
mutual_compat!(@pairs [$($done,)* $first] $($rest),*);
};
}
macro_rules! any_compat {
($any:ty; $($ty:ty),+ $(,)?) => {
$(
impl Compatible<$ty> for $any {}
impl Compatible<$any> for $ty {}
)+
};
}
macro_rules! impl_placeholder_compat {
($($ty:ty),+ $(,)?) => {
$(
impl Compatible<crate::Placeholder> for $ty {}
impl Compatible<$ty> for crate::Placeholder {}
)+
};
}
macro_rules! assign_to {
($target:ty; $($src:ty),+ $(,)?) => {
$(impl Assignable<$src> for $target {})+
};
}
macro_rules! mutual_assign {
($($ty:ty),+ $(,)?) => {
mutual_assign!(@pairs [] $($ty),+);
};
(@pairs [$($done:ty),*]) => {};
(@pairs [$($done:ty),*] $first:ty $(, $rest:ty)*) => {
$(
impl Assignable<$rest> for $first {}
impl Assignable<$first> for $rest {}
)*
mutual_assign!(@pairs [$($done,)* $first] $($rest),*);
};
}
macro_rules! any_assign {
($any:ty; $($ty:ty),+ $(,)?) => {
$(impl Assignable<$ty> for $any {})+
};
}
impl<T: DataType> Compatible<Self> for crate::Array<T> {}
impl Compatible<Self> for crate::Placeholder {}
impl<T: DataType> Assignable<Self> for crate::Array<T> {}
impl_reflexive_compat!(
crate::sqlite::types::Integer,
crate::sqlite::types::Text,
crate::sqlite::types::Real,
crate::sqlite::types::Blob,
crate::sqlite::types::Numeric,
crate::sqlite::types::Any,
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4,
crate::postgres::types::Float8,
crate::postgres::types::Varchar,
crate::postgres::types::Text,
crate::postgres::types::Char,
crate::postgres::types::Bytea,
crate::postgres::types::Boolean,
crate::postgres::types::Timestamptz,
crate::postgres::types::Timestamp,
crate::postgres::types::Date,
crate::postgres::types::Time,
crate::postgres::types::Timetz,
crate::postgres::types::Numeric,
crate::postgres::types::Uuid,
crate::postgres::types::Json,
crate::postgres::types::Jsonb,
crate::postgres::types::Any,
crate::postgres::types::Interval,
crate::postgres::types::Inet,
crate::postgres::types::Cidr,
crate::postgres::types::MacAddr,
crate::postgres::types::MacAddr8,
crate::postgres::types::Point,
crate::postgres::types::LineString,
crate::postgres::types::Rect,
crate::postgres::types::BitString,
crate::postgres::types::Line,
crate::postgres::types::LineSegment,
crate::postgres::types::Polygon,
crate::postgres::types::Circle,
crate::postgres::types::Enum,
);
impl_reflexive_assign!(
crate::sqlite::types::Integer,
crate::sqlite::types::Text,
crate::sqlite::types::Real,
crate::sqlite::types::Blob,
crate::sqlite::types::Numeric,
crate::sqlite::types::Any,
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4,
crate::postgres::types::Float8,
crate::postgres::types::Varchar,
crate::postgres::types::Text,
crate::postgres::types::Char,
crate::postgres::types::Bytea,
crate::postgres::types::Boolean,
crate::postgres::types::Timestamptz,
crate::postgres::types::Timestamp,
crate::postgres::types::Date,
crate::postgres::types::Time,
crate::postgres::types::Timetz,
crate::postgres::types::Numeric,
crate::postgres::types::Uuid,
crate::postgres::types::Json,
crate::postgres::types::Jsonb,
crate::postgres::types::Any,
crate::postgres::types::Interval,
crate::postgres::types::Inet,
crate::postgres::types::Cidr,
crate::postgres::types::MacAddr,
crate::postgres::types::MacAddr8,
crate::postgres::types::Point,
crate::postgres::types::LineString,
crate::postgres::types::Rect,
crate::postgres::types::BitString,
crate::postgres::types::Line,
crate::postgres::types::LineSegment,
crate::postgres::types::Polygon,
crate::postgres::types::Circle,
crate::postgres::types::Enum,
);
mutual_compat!(
crate::sqlite::types::Integer,
crate::sqlite::types::Real,
crate::sqlite::types::Numeric
);
mutual_compat!(crate::sqlite::types::Text, crate::sqlite::types::Blob);
any_compat!(crate::sqlite::types::Any;
crate::sqlite::types::Integer,
crate::sqlite::types::Text,
crate::sqlite::types::Real,
crate::sqlite::types::Blob,
crate::sqlite::types::Numeric
);
impl_placeholder_compat!(
crate::sqlite::types::Integer,
crate::sqlite::types::Text,
crate::sqlite::types::Real,
crate::sqlite::types::Blob,
crate::sqlite::types::Numeric,
crate::sqlite::types::Any
);
mutual_compat!(
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8
);
mutual_compat!(
crate::postgres::types::Float4,
crate::postgres::types::Float8
);
macro_rules! cross_compat {
([$first_a:ty $(, $rest_a:ty)* $(,)?], [$($b:ty),+ $(,)?]) => {
$(
impl Compatible<$b> for $first_a {}
impl Compatible<$first_a> for $b {}
)+
cross_compat!([$($rest_a),*], [$($b),+]);
};
([], [$($b:ty),+ $(,)?]) => {};
}
cross_compat!(
[
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8
],
[
crate::postgres::types::Float4,
crate::postgres::types::Float8
]
);
any_compat!(crate::postgres::types::Numeric;
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4,
crate::postgres::types::Float8
);
mutual_compat!(
crate::postgres::types::Text,
crate::postgres::types::Varchar,
crate::postgres::types::Char
);
mutual_compat!(
crate::postgres::types::Timestamptz,
crate::postgres::types::Timestamp
);
mutual_compat!(crate::postgres::types::Time, crate::postgres::types::Timetz);
mutual_compat!(crate::postgres::types::Json, crate::postgres::types::Jsonb);
cross_compat!(
[crate::postgres::types::Text],
[
crate::postgres::types::Timestamptz,
crate::postgres::types::Timestamp,
crate::postgres::types::Date,
crate::postgres::types::Time
]
);
mutual_compat!(crate::postgres::types::Inet, crate::postgres::types::Cidr);
mutual_compat!(
crate::postgres::types::MacAddr,
crate::postgres::types::MacAddr8
);
cross_compat!(
[crate::postgres::types::Enum],
[
crate::postgres::types::Text,
crate::postgres::types::Varchar,
crate::postgres::types::Char
]
);
any_compat!(crate::postgres::types::Any;
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4,
crate::postgres::types::Float8,
crate::postgres::types::Varchar,
crate::postgres::types::Text,
crate::postgres::types::Char,
crate::postgres::types::Bytea,
crate::postgres::types::Boolean,
crate::postgres::types::Timestamptz,
crate::postgres::types::Timestamp,
crate::postgres::types::Date,
crate::postgres::types::Time,
crate::postgres::types::Timetz,
crate::postgres::types::Numeric,
crate::postgres::types::Uuid,
crate::postgres::types::Json,
crate::postgres::types::Jsonb,
crate::postgres::types::Interval,
crate::postgres::types::Inet,
crate::postgres::types::Cidr,
crate::postgres::types::MacAddr,
crate::postgres::types::MacAddr8,
crate::postgres::types::Point,
crate::postgres::types::LineString,
crate::postgres::types::Rect,
crate::postgres::types::BitString,
crate::postgres::types::Line,
crate::postgres::types::LineSegment,
crate::postgres::types::Polygon,
crate::postgres::types::Circle,
crate::postgres::types::Enum
);
impl_placeholder_compat!(
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4,
crate::postgres::types::Float8,
crate::postgres::types::Varchar,
crate::postgres::types::Text,
crate::postgres::types::Char,
crate::postgres::types::Bytea,
crate::postgres::types::Boolean,
crate::postgres::types::Timestamptz,
crate::postgres::types::Timestamp,
crate::postgres::types::Date,
crate::postgres::types::Time,
crate::postgres::types::Timetz,
crate::postgres::types::Numeric,
crate::postgres::types::Uuid,
crate::postgres::types::Json,
crate::postgres::types::Jsonb,
crate::postgres::types::Any,
crate::postgres::types::Interval,
crate::postgres::types::Inet,
crate::postgres::types::Cidr,
crate::postgres::types::MacAddr,
crate::postgres::types::MacAddr8,
crate::postgres::types::Point,
crate::postgres::types::LineString,
crate::postgres::types::Rect,
crate::postgres::types::BitString,
crate::postgres::types::Line,
crate::postgres::types::LineSegment,
crate::postgres::types::Polygon,
crate::postgres::types::Circle,
crate::postgres::types::Enum
);
assign_to!(crate::sqlite::types::Real; crate::sqlite::types::Integer);
assign_to!(crate::sqlite::types::Numeric; crate::sqlite::types::Integer, crate::sqlite::types::Real);
any_assign!(crate::sqlite::types::Any;
crate::sqlite::types::Integer,
crate::sqlite::types::Text,
crate::sqlite::types::Real,
crate::sqlite::types::Blob,
crate::sqlite::types::Numeric
);
assign_to!(crate::postgres::types::Int4; crate::postgres::types::Int2);
assign_to!(crate::postgres::types::Int8; crate::postgres::types::Int2, crate::postgres::types::Int4);
assign_to!(crate::postgres::types::Float4;
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8
);
assign_to!(crate::postgres::types::Float8;
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4
);
assign_to!(crate::postgres::types::Numeric;
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4,
crate::postgres::types::Float8
);
mutual_assign!(
crate::postgres::types::Text,
crate::postgres::types::Varchar,
crate::postgres::types::Char
);
assign_to!(crate::postgres::types::Varchar; crate::postgres::types::Enum);
assign_to!(crate::postgres::types::Text; crate::postgres::types::Enum);
assign_to!(crate::postgres::types::Char; crate::postgres::types::Enum);
assign_to!(crate::postgres::types::Timestamptz; crate::postgres::types::Timestamp);
assign_to!(crate::postgres::types::Timetz; crate::postgres::types::Time);
assign_to!(crate::postgres::types::Jsonb; crate::postgres::types::Json);
assign_to!(crate::postgres::types::Cidr; crate::postgres::types::Inet);
any_assign!(crate::postgres::types::Any;
crate::postgres::types::Int2,
crate::postgres::types::Int4,
crate::postgres::types::Int8,
crate::postgres::types::Float4,
crate::postgres::types::Float8,
crate::postgres::types::Varchar,
crate::postgres::types::Text,
crate::postgres::types::Char,
crate::postgres::types::Bytea,
crate::postgres::types::Boolean,
crate::postgres::types::Timestamptz,
crate::postgres::types::Timestamp,
crate::postgres::types::Date,
crate::postgres::types::Time,
crate::postgres::types::Timetz,
crate::postgres::types::Numeric,
crate::postgres::types::Uuid,
crate::postgres::types::Json,
crate::postgres::types::Jsonb,
crate::postgres::types::Interval,
crate::postgres::types::Inet,
crate::postgres::types::Cidr,
crate::postgres::types::MacAddr,
crate::postgres::types::MacAddr8,
crate::postgres::types::Point,
crate::postgres::types::LineString,
crate::postgres::types::Rect,
crate::postgres::types::BitString,
crate::postgres::types::Line,
crate::postgres::types::LineSegment,
crate::postgres::types::Polygon,
crate::postgres::types::Circle,
crate::postgres::types::Enum
);
macro_rules! seq_dual {
(@acc $callback:ident [$($sa:ident),*] [$($da:ident),*]) => {};
(@acc $callback:ident [$($sa:ident),*] [$($da:ident),*] ($s:ident, $d:ident) $($rest:tt)*) => {
$callback!($($sa,)* $s; $($da,)* $d);
seq_dual!(@acc $callback [$($sa,)* $s] [$($da,)* $d] $($rest)*);
};
($callback:ident; $($pairs:tt)+) => {
seq_dual!(@acc $callback [] [] $($pairs)+);
};
(@from $callback:ident [$($sa:ident),*] [$($da:ident),*]; $($pairs:tt)+) => {
seq_dual!(@acc $callback [$($sa),*] [$($da),*] $($pairs)+);
};
}
macro_rules! with_dual_col_sizes_8 {
($callback:ident) => {
seq_dual!($callback;
(T0,U0) (T1,U1) (T2,U2) (T3,U3)
(T4,U4) (T5,U5) (T6,U6) (T7,U7)
);
};
}
#[allow(unused_macros)]
macro_rules! with_dual_col_sizes_16 {
($callback:ident) => {
seq_dual!(@from $callback
[T0,T1,T2,T3,T4,T5,T6,T7]
[U0,U1,U2,U3,U4,U5,U6,U7];
(T8,U8) (T9,U9) (T10,U10) (T11,U11)
(T12,U12) (T13,U13) (T14,U14) (T15,U15)
);
};
}
#[allow(unused_macros)]
macro_rules! with_dual_col_sizes_32 {
($callback:ident) => {
seq_dual!(@from $callback
[T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15]
[U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15];
(T16,U16) (T17,U17) (T18,U18) (T19,U19)
(T20,U20) (T21,U21) (T22,U22) (T23,U23)
(T24,U24) (T25,U25) (T26,U26) (T27,U27)
(T28,U28) (T29,U29) (T30,U30) (T31,U31)
);
};
}
#[allow(unused_macros)]
macro_rules! with_dual_col_sizes_64 {
($callback:ident) => {
seq_dual!(@from $callback
[T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31]
[U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15,
U16,U17,U18,U19,U20,U21,U22,U23,U24,U25,U26,U27,U28,U29,U30,U31];
(T32,U32) (T33,U33) (T34,U34) (T35,U35)
(T36,U36) (T37,U37) (T38,U38) (T39,U39)
(T40,U40) (T41,U41) (T42,U42) (T43,U43)
(T44,U44) (T45,U45) (T46,U46) (T47,U47)
(T48,U48) (T49,U49) (T50,U50) (T51,U51)
(T52,U52) (T53,U53) (T54,U54) (T55,U55)
(T56,U56) (T57,U57) (T58,U58) (T59,U59)
(T60,U60) (T61,U61) (T62,U62) (T63,U63)
);
};
}
#[allow(unused_macros)]
macro_rules! with_dual_col_sizes_128 {
($callback:ident) => {
seq_dual!(@from $callback
[T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,
T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,
T48,T49,T50,T51,T52,T53,T54,T55,T56,T57,T58,T59,T60,T61,T62,T63]
[U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15,
U16,U17,U18,U19,U20,U21,U22,U23,U24,U25,U26,U27,U28,U29,U30,U31,
U32,U33,U34,U35,U36,U37,U38,U39,U40,U41,U42,U43,U44,U45,U46,U47,
U48,U49,U50,U51,U52,U53,U54,U55,U56,U57,U58,U59,U60,U61,U62,U63];
(T64,U64) (T65,U65) (T66,U66) (T67,U67)
(T68,U68) (T69,U69) (T70,U70) (T71,U71)
(T72,U72) (T73,U73) (T74,U74) (T75,U75)
(T76,U76) (T77,U77) (T78,U78) (T79,U79)
(T80,U80) (T81,U81) (T82,U82) (T83,U83)
(T84,U84) (T85,U85) (T86,U86) (T87,U87)
(T88,U88) (T89,U89) (T90,U90) (T91,U91)
(T92,U92) (T93,U93) (T94,U94) (T95,U95)
(T96,U96) (T97,U97) (T98,U98) (T99,U99)
(T100,U100) (T101,U101) (T102,U102) (T103,U103)
(T104,U104) (T105,U105) (T106,U106) (T107,U107)
(T108,U108) (T109,U109) (T110,U110) (T111,U111)
(T112,U112) (T113,U113) (T114,U114) (T115,U115)
(T116,U116) (T117,U117) (T118,U118) (T119,U119)
(T120,U120) (T121,U121) (T122,U122) (T123,U123)
(T124,U124) (T125,U125) (T126,U126) (T127,U127)
);
};
}
#[allow(unused_macros)]
macro_rules! with_dual_col_sizes_200 {
($callback:ident) => {
seq_dual!(@from $callback
[T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,
T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,
T48,T49,T50,T51,T52,T53,T54,T55,T56,T57,T58,T59,T60,T61,T62,T63,
T64,T65,T66,T67,T68,T69,T70,T71,T72,T73,T74,T75,T76,T77,T78,T79,
T80,T81,T82,T83,T84,T85,T86,T87,T88,T89,T90,T91,T92,T93,T94,T95,
T96,T97,T98,T99,T100,T101,T102,T103,T104,T105,T106,T107,T108,T109,T110,T111,
T112,T113,T114,T115,T116,T117,T118,T119,T120,T121,T122,T123,T124,T125,T126,T127]
[U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15,
U16,U17,U18,U19,U20,U21,U22,U23,U24,U25,U26,U27,U28,U29,U30,U31,
U32,U33,U34,U35,U36,U37,U38,U39,U40,U41,U42,U43,U44,U45,U46,U47,
U48,U49,U50,U51,U52,U53,U54,U55,U56,U57,U58,U59,U60,U61,U62,U63,
U64,U65,U66,U67,U68,U69,U70,U71,U72,U73,U74,U75,U76,U77,U78,U79,
U80,U81,U82,U83,U84,U85,U86,U87,U88,U89,U90,U91,U92,U93,U94,U95,
U96,U97,U98,U99,U100,U101,U102,U103,U104,U105,U106,U107,U108,U109,U110,U111,
U112,U113,U114,U115,U116,U117,U118,U119,U120,U121,U122,U123,U124,U125,U126,U127];
(T128,U128) (T129,U129) (T130,U130) (T131,U131)
(T132,U132) (T133,U133) (T134,U134) (T135,U135)
(T136,U136) (T137,U137) (T138,U138) (T139,U139)
(T140,U140) (T141,U141) (T142,U142) (T143,U143)
(T144,U144) (T145,U145) (T146,U146) (T147,U147)
(T148,U148) (T149,U149) (T150,U150) (T151,U151)
(T152,U152) (T153,U153) (T154,U154) (T155,U155)
(T156,U156) (T157,U157) (T158,U158) (T159,U159)
(T160,U160) (T161,U161) (T162,U162) (T163,U163)
(T164,U164) (T165,U165) (T166,U166) (T167,U167)
(T168,U168) (T169,U169) (T170,U170) (T171,U171)
(T172,U172) (T173,U173) (T174,U174) (T175,U175)
(T176,U176) (T177,U177) (T178,U178) (T179,U179)
(T180,U180) (T181,U181) (T182,U182) (T183,U183)
(T184,U184) (T185,U185) (T186,U186) (T187,U187)
(T188,U188) (T189,U189) (T190,U190) (T191,U191)
(T192,U192) (T193,U193) (T194,U194) (T195,U195)
(T196,U196) (T197,U197) (T198,U198) (T199,U199)
);
};
}
macro_rules! impl_tuple_compatible {
($($T:ident),+; $($U:ident),+) => {
impl<$($T, $U),+> Compatible<($($U,)+)> for ($($T,)+)
where
$($T: DataType + Compatible<$U>, $U: DataType,)+
{}
};
}
macro_rules! impl_tuple_assignable {
($($S:ident),+; $($D:ident),+) => {
impl<$($S, $D),+> Assignable<($($S,)+)> for ($($D,)+)
where
$($S: DataType, $D: DataType + Assignable<$S>,)+
{}
};
}
with_dual_col_sizes_8!(impl_tuple_compatible);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_dual_col_sizes_16!(impl_tuple_compatible);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_dual_col_sizes_32!(impl_tuple_compatible);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_dual_col_sizes_64!(impl_tuple_compatible);
#[cfg(any(feature = "col128", feature = "col200"))]
with_dual_col_sizes_128!(impl_tuple_compatible);
#[cfg(feature = "col200")]
with_dual_col_sizes_200!(impl_tuple_compatible);
with_dual_col_sizes_8!(impl_tuple_assignable);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_dual_col_sizes_16!(impl_tuple_assignable);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_dual_col_sizes_32!(impl_tuple_assignable);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_dual_col_sizes_64!(impl_tuple_assignable);
#[cfg(any(feature = "col128", feature = "col200"))]
with_dual_col_sizes_128!(impl_tuple_assignable);
#[cfg(feature = "col200")]
with_dual_col_sizes_200!(impl_tuple_assignable);