Skip to main content

drizzle_types/sql/
coerce.rs

1use super::DataType;
2
3#[diagnostic::on_unimplemented(
4    message = "SQL type `{Self}` is not compatible with `{Rhs}`",
5    label = "these SQL types cannot be compared or coerced",
6    note = "compatible types include: integers with integers/floats, text with text/varchar, and any type with itself"
7)]
8pub trait Compatible<Rhs: DataType = Self>: DataType {}
9
10#[diagnostic::on_unimplemented(
11    message = "SQL type `{Self}` is not assignable from `{Rhs}`",
12    label = "this value type cannot be bound to the placeholder/column type",
13    note = "assignment is stricter than comparison compatibility; use a value matching the target SQL marker"
14)]
15pub trait Assignable<Rhs: DataType = Self>: DataType {}
16
17// =============================================================================
18// Core macros
19// =============================================================================
20
21macro_rules! impl_reflexive_compat {
22    ($($ty:ty),+ $(,)?) => {
23        $(impl Compatible<$ty> for $ty {})+
24    };
25}
26
27macro_rules! impl_reflexive_assign {
28    ($($ty:ty),+ $(,)?) => {
29        $(impl Assignable<$ty> for $ty {})+
30    };
31}
32
33/// Generate mutual (bidirectional) `Compatible` impls for all unique cross-pairs in a group.
34/// Does NOT generate reflexive impls (those come from `impl_reflexive_compat!`).
35///
36/// `mutual_compat!(A, B, C)` expands to:
37///   Compatible<B> for A, Compatible<A> for B,
38///   Compatible<C> for A, Compatible<A> for C,
39///   Compatible<C> for B, Compatible<B> for C
40macro_rules! mutual_compat {
41    // Entry: dispatch to pair generation
42    ($($ty:ty),+ $(,)?) => {
43        mutual_compat!(@pairs [] $($ty),+);
44    };
45    // Base case: no more types to process
46    (@pairs [$($done:ty),*]) => {};
47    // Recursive case: take first type, pair it with all remaining
48    (@pairs [$($done:ty),*] $first:ty $(, $rest:ty)*) => {
49        $(
50            impl Compatible<$rest> for $first {}
51            impl Compatible<$first> for $rest {}
52        )*
53        mutual_compat!(@pairs [$($done,)* $first] $($rest),*);
54    };
55}
56
57/// Generate bidirectional `Compatible` impls between an "any" type and a list of types.
58macro_rules! any_compat {
59    ($any:ty; $($ty:ty),+ $(,)?) => {
60        $(
61            impl Compatible<$ty> for $any {}
62            impl Compatible<$any> for $ty {}
63        )+
64    };
65}
66
67macro_rules! impl_placeholder_compat {
68    ($($ty:ty),+ $(,)?) => {
69        $(
70            impl Compatible<crate::Placeholder> for $ty {}
71            impl Compatible<$ty> for crate::Placeholder {}
72        )+
73    };
74}
75
76/// Generate directional `Assignable` impls: each source can be assigned to the target.
77/// `assign_to!(Target; Src1, Src2)` → `Assignable<Src1> for Target`, `Assignable<Src2> for Target`
78macro_rules! assign_to {
79    ($target:ty; $($src:ty),+ $(,)?) => {
80        $(impl Assignable<$src> for $target {})+
81    };
82}
83
84/// Generate bidirectional `Assignable` for all cross-pairs in a group (mutual assignment).
85/// Does NOT generate reflexive impls (those come from `impl_reflexive_assign!`).
86macro_rules! mutual_assign {
87    ($($ty:ty),+ $(,)?) => {
88        mutual_assign!(@pairs [] $($ty),+);
89    };
90    (@pairs [$($done:ty),*]) => {};
91    (@pairs [$($done:ty),*] $first:ty $(, $rest:ty)*) => {
92        $(
93            impl Assignable<$rest> for $first {}
94            impl Assignable<$first> for $rest {}
95        )*
96        mutual_assign!(@pairs [$($done,)* $first] $($rest),*);
97    };
98}
99
100/// Generate `Assignable` from every source to a single "any" target.
101macro_rules! any_assign {
102    ($any:ty; $($ty:ty),+ $(,)?) => {
103        $(impl Assignable<$ty> for $any {})+
104    };
105}
106
107// =============================================================================
108// Generic impls
109// =============================================================================
110
111impl<T: DataType> Compatible<Self> for crate::Array<T> {}
112impl Compatible<Self> for crate::Placeholder {}
113impl<T: DataType> Assignable<Self> for crate::Array<T> {}
114
115// Reflexive compat & assign for all concrete types
116impl_reflexive_compat!(
117    crate::sqlite::types::Integer,
118    crate::sqlite::types::Text,
119    crate::sqlite::types::Real,
120    crate::sqlite::types::Blob,
121    crate::sqlite::types::Numeric,
122    crate::sqlite::types::Any,
123    crate::postgres::types::Int2,
124    crate::postgres::types::Int4,
125    crate::postgres::types::Int8,
126    crate::postgres::types::Float4,
127    crate::postgres::types::Float8,
128    crate::postgres::types::Varchar,
129    crate::postgres::types::Text,
130    crate::postgres::types::Char,
131    crate::postgres::types::Bytea,
132    crate::postgres::types::Boolean,
133    crate::postgres::types::Timestamptz,
134    crate::postgres::types::Timestamp,
135    crate::postgres::types::Date,
136    crate::postgres::types::Time,
137    crate::postgres::types::Timetz,
138    crate::postgres::types::Numeric,
139    crate::postgres::types::Uuid,
140    crate::postgres::types::Json,
141    crate::postgres::types::Jsonb,
142    crate::postgres::types::Any,
143    crate::postgres::types::Interval,
144    crate::postgres::types::Inet,
145    crate::postgres::types::Cidr,
146    crate::postgres::types::MacAddr,
147    crate::postgres::types::MacAddr8,
148    crate::postgres::types::Point,
149    crate::postgres::types::LineString,
150    crate::postgres::types::Rect,
151    crate::postgres::types::BitString,
152    crate::postgres::types::Line,
153    crate::postgres::types::LineSegment,
154    crate::postgres::types::Polygon,
155    crate::postgres::types::Circle,
156    crate::postgres::types::Enum,
157);
158
159impl_reflexive_assign!(
160    crate::sqlite::types::Integer,
161    crate::sqlite::types::Text,
162    crate::sqlite::types::Real,
163    crate::sqlite::types::Blob,
164    crate::sqlite::types::Numeric,
165    crate::sqlite::types::Any,
166    crate::postgres::types::Int2,
167    crate::postgres::types::Int4,
168    crate::postgres::types::Int8,
169    crate::postgres::types::Float4,
170    crate::postgres::types::Float8,
171    crate::postgres::types::Varchar,
172    crate::postgres::types::Text,
173    crate::postgres::types::Char,
174    crate::postgres::types::Bytea,
175    crate::postgres::types::Boolean,
176    crate::postgres::types::Timestamptz,
177    crate::postgres::types::Timestamp,
178    crate::postgres::types::Date,
179    crate::postgres::types::Time,
180    crate::postgres::types::Timetz,
181    crate::postgres::types::Numeric,
182    crate::postgres::types::Uuid,
183    crate::postgres::types::Json,
184    crate::postgres::types::Jsonb,
185    crate::postgres::types::Any,
186    crate::postgres::types::Interval,
187    crate::postgres::types::Inet,
188    crate::postgres::types::Cidr,
189    crate::postgres::types::MacAddr,
190    crate::postgres::types::MacAddr8,
191    crate::postgres::types::Point,
192    crate::postgres::types::LineString,
193    crate::postgres::types::Rect,
194    crate::postgres::types::BitString,
195    crate::postgres::types::Line,
196    crate::postgres::types::LineSegment,
197    crate::postgres::types::Polygon,
198    crate::postgres::types::Circle,
199    crate::postgres::types::Enum,
200);
201
202// =============================================================================
203// SQLite compatibility (category-based)
204// =============================================================================
205
206// SQLite numeric family: Integer ↔ Real ↔ Numeric (all mutually compatible)
207mutual_compat!(
208    crate::sqlite::types::Integer,
209    crate::sqlite::types::Real,
210    crate::sqlite::types::Numeric
211);
212
213// Blob ↔ Text (SQLite stores UUIDs, etc. as either)
214mutual_compat!(crate::sqlite::types::Text, crate::sqlite::types::Blob);
215
216// Any ↔ all SQLite types
217any_compat!(crate::sqlite::types::Any;
218    crate::sqlite::types::Integer,
219    crate::sqlite::types::Text,
220    crate::sqlite::types::Real,
221    crate::sqlite::types::Blob,
222    crate::sqlite::types::Numeric
223);
224
225impl_placeholder_compat!(
226    crate::sqlite::types::Integer,
227    crate::sqlite::types::Text,
228    crate::sqlite::types::Real,
229    crate::sqlite::types::Blob,
230    crate::sqlite::types::Numeric,
231    crate::sqlite::types::Any
232);
233
234// =============================================================================
235// PostgreSQL compatibility (category-based)
236// =============================================================================
237
238// Integer family: Int2 ↔ Int4 ↔ Int8 (all mutually compatible)
239mutual_compat!(
240    crate::postgres::types::Int2,
241    crate::postgres::types::Int4,
242    crate::postgres::types::Int8
243);
244
245// Float family: Float4 ↔ Float8
246mutual_compat!(
247    crate::postgres::types::Float4,
248    crate::postgres::types::Float8
249);
250
251// Cross-numeric: all integers ↔ all floats
252// (Int2, Int4, Int8) × (Float4, Float8)
253/// Generate cross-product `Compatible` impls between two groups of types.
254/// Every type in group A becomes compatible with every type in group B (bidirectional).
255macro_rules! cross_compat {
256    ([$first_a:ty $(, $rest_a:ty)* $(,)?], [$($b:ty),+ $(,)?]) => {
257        // Expand first_a × all B
258        $(
259            impl Compatible<$b> for $first_a {}
260            impl Compatible<$first_a> for $b {}
261        )+
262        // Recurse for remaining A types
263        cross_compat!([$($rest_a),*], [$($b),+]);
264    };
265    // Base case: empty A list
266    ([], [$($b:ty),+ $(,)?]) => {};
267}
268
269cross_compat!(
270    [
271        crate::postgres::types::Int2,
272        crate::postgres::types::Int4,
273        crate::postgres::types::Int8
274    ],
275    [
276        crate::postgres::types::Float4,
277        crate::postgres::types::Float8
278    ]
279);
280
281// Numeric ↔ all numeric types (Int2, Int4, Int8, Float4, Float8)
282any_compat!(crate::postgres::types::Numeric;
283    crate::postgres::types::Int2,
284    crate::postgres::types::Int4,
285    crate::postgres::types::Int8,
286    crate::postgres::types::Float4,
287    crate::postgres::types::Float8
288);
289
290// Text family: Text ↔ Varchar ↔ Char (all mutually compatible)
291mutual_compat!(
292    crate::postgres::types::Text,
293    crate::postgres::types::Varchar,
294    crate::postgres::types::Char
295);
296
297// Temporal cross-compatibility pairs
298mutual_compat!(
299    crate::postgres::types::Timestamptz,
300    crate::postgres::types::Timestamp
301);
302mutual_compat!(crate::postgres::types::Time, crate::postgres::types::Timetz);
303
304// JSON cross-compatibility
305mutual_compat!(crate::postgres::types::Json, crate::postgres::types::Jsonb);
306
307// Text ↔ Temporal (string comparisons with timestamps)
308cross_compat!(
309    [crate::postgres::types::Text],
310    [
311        crate::postgres::types::Timestamptz,
312        crate::postgres::types::Timestamp,
313        crate::postgres::types::Date,
314        crate::postgres::types::Time
315    ]
316);
317
318// Network types: Inet ↔ Cidr
319mutual_compat!(crate::postgres::types::Inet, crate::postgres::types::Cidr);
320
321// MAC address types: MacAddr ↔ MacAddr8
322mutual_compat!(
323    crate::postgres::types::MacAddr,
324    crate::postgres::types::MacAddr8
325);
326
327// Enum ↔ Text family
328cross_compat!(
329    [crate::postgres::types::Enum],
330    [
331        crate::postgres::types::Text,
332        crate::postgres::types::Varchar,
333        crate::postgres::types::Char
334    ]
335);
336
337// Any ↔ all PostgreSQL types
338any_compat!(crate::postgres::types::Any;
339    crate::postgres::types::Int2,
340    crate::postgres::types::Int4,
341    crate::postgres::types::Int8,
342    crate::postgres::types::Float4,
343    crate::postgres::types::Float8,
344    crate::postgres::types::Varchar,
345    crate::postgres::types::Text,
346    crate::postgres::types::Char,
347    crate::postgres::types::Bytea,
348    crate::postgres::types::Boolean,
349    crate::postgres::types::Timestamptz,
350    crate::postgres::types::Timestamp,
351    crate::postgres::types::Date,
352    crate::postgres::types::Time,
353    crate::postgres::types::Timetz,
354    crate::postgres::types::Numeric,
355    crate::postgres::types::Uuid,
356    crate::postgres::types::Json,
357    crate::postgres::types::Jsonb,
358    crate::postgres::types::Interval,
359    crate::postgres::types::Inet,
360    crate::postgres::types::Cidr,
361    crate::postgres::types::MacAddr,
362    crate::postgres::types::MacAddr8,
363    crate::postgres::types::Point,
364    crate::postgres::types::LineString,
365    crate::postgres::types::Rect,
366    crate::postgres::types::BitString,
367    crate::postgres::types::Line,
368    crate::postgres::types::LineSegment,
369    crate::postgres::types::Polygon,
370    crate::postgres::types::Circle,
371    crate::postgres::types::Enum
372);
373
374impl_placeholder_compat!(
375    crate::postgres::types::Int2,
376    crate::postgres::types::Int4,
377    crate::postgres::types::Int8,
378    crate::postgres::types::Float4,
379    crate::postgres::types::Float8,
380    crate::postgres::types::Varchar,
381    crate::postgres::types::Text,
382    crate::postgres::types::Char,
383    crate::postgres::types::Bytea,
384    crate::postgres::types::Boolean,
385    crate::postgres::types::Timestamptz,
386    crate::postgres::types::Timestamp,
387    crate::postgres::types::Date,
388    crate::postgres::types::Time,
389    crate::postgres::types::Timetz,
390    crate::postgres::types::Numeric,
391    crate::postgres::types::Uuid,
392    crate::postgres::types::Json,
393    crate::postgres::types::Jsonb,
394    crate::postgres::types::Any,
395    crate::postgres::types::Interval,
396    crate::postgres::types::Inet,
397    crate::postgres::types::Cidr,
398    crate::postgres::types::MacAddr,
399    crate::postgres::types::MacAddr8,
400    crate::postgres::types::Point,
401    crate::postgres::types::LineString,
402    crate::postgres::types::Rect,
403    crate::postgres::types::BitString,
404    crate::postgres::types::Line,
405    crate::postgres::types::LineSegment,
406    crate::postgres::types::Polygon,
407    crate::postgres::types::Circle,
408    crate::postgres::types::Enum
409);
410
411// =============================================================================
412// Assignment compatibility (bind-time)
413// =============================================================================
414// Assignment is stricter than comparison: only wider types accept narrower values.
415
416// SQLite assignment
417assign_to!(crate::sqlite::types::Real; crate::sqlite::types::Integer);
418assign_to!(crate::sqlite::types::Numeric; crate::sqlite::types::Integer, crate::sqlite::types::Real);
419any_assign!(crate::sqlite::types::Any;
420    crate::sqlite::types::Integer,
421    crate::sqlite::types::Text,
422    crate::sqlite::types::Real,
423    crate::sqlite::types::Blob,
424    crate::sqlite::types::Numeric
425);
426
427// PostgreSQL integer widening: Int2 → Int4 → Int8
428assign_to!(crate::postgres::types::Int4; crate::postgres::types::Int2);
429assign_to!(crate::postgres::types::Int8; crate::postgres::types::Int2, crate::postgres::types::Int4);
430
431// Int → Float widening
432assign_to!(crate::postgres::types::Float4;
433    crate::postgres::types::Int2,
434    crate::postgres::types::Int4,
435    crate::postgres::types::Int8
436);
437assign_to!(crate::postgres::types::Float8;
438    crate::postgres::types::Int2,
439    crate::postgres::types::Int4,
440    crate::postgres::types::Int8,
441    crate::postgres::types::Float4
442);
443
444// Numeric accepts all numeric types
445assign_to!(crate::postgres::types::Numeric;
446    crate::postgres::types::Int2,
447    crate::postgres::types::Int4,
448    crate::postgres::types::Int8,
449    crate::postgres::types::Float4,
450    crate::postgres::types::Float8
451);
452
453// Text family: all mutually assignable
454mutual_assign!(
455    crate::postgres::types::Text,
456    crate::postgres::types::Varchar,
457    crate::postgres::types::Char
458);
459
460// Enum → Text family
461assign_to!(crate::postgres::types::Varchar; crate::postgres::types::Enum);
462assign_to!(crate::postgres::types::Text; crate::postgres::types::Enum);
463assign_to!(crate::postgres::types::Char; crate::postgres::types::Enum);
464
465// Temporal and JSON assignment
466assign_to!(crate::postgres::types::Timestamptz; crate::postgres::types::Timestamp);
467assign_to!(crate::postgres::types::Timetz; crate::postgres::types::Time);
468assign_to!(crate::postgres::types::Jsonb; crate::postgres::types::Json);
469
470// Network assignment
471assign_to!(crate::postgres::types::Cidr; crate::postgres::types::Inet);
472
473// Any accepts all concrete PostgreSQL markers
474any_assign!(crate::postgres::types::Any;
475    crate::postgres::types::Int2,
476    crate::postgres::types::Int4,
477    crate::postgres::types::Int8,
478    crate::postgres::types::Float4,
479    crate::postgres::types::Float8,
480    crate::postgres::types::Varchar,
481    crate::postgres::types::Text,
482    crate::postgres::types::Char,
483    crate::postgres::types::Bytea,
484    crate::postgres::types::Boolean,
485    crate::postgres::types::Timestamptz,
486    crate::postgres::types::Timestamp,
487    crate::postgres::types::Date,
488    crate::postgres::types::Time,
489    crate::postgres::types::Timetz,
490    crate::postgres::types::Numeric,
491    crate::postgres::types::Uuid,
492    crate::postgres::types::Json,
493    crate::postgres::types::Jsonb,
494    crate::postgres::types::Interval,
495    crate::postgres::types::Inet,
496    crate::postgres::types::Cidr,
497    crate::postgres::types::MacAddr,
498    crate::postgres::types::MacAddr8,
499    crate::postgres::types::Point,
500    crate::postgres::types::LineString,
501    crate::postgres::types::Rect,
502    crate::postgres::types::BitString,
503    crate::postgres::types::Line,
504    crate::postgres::types::LineSegment,
505    crate::postgres::types::Polygon,
506    crate::postgres::types::Circle,
507    crate::postgres::types::Enum
508);
509
510// =============================================================================
511// Tuple compatibility
512// =============================================================================
513
514macro_rules! seq_dual {
515    (@acc $callback:ident [$($sa:ident),*] [$($da:ident),*]) => {};
516    (@acc $callback:ident [$($sa:ident),*] [$($da:ident),*] ($s:ident, $d:ident) $($rest:tt)*) => {
517        $callback!($($sa,)* $s; $($da,)* $d);
518        seq_dual!(@acc $callback [$($sa,)* $s] [$($da,)* $d] $($rest)*);
519    };
520    ($callback:ident; $($pairs:tt)+) => {
521        seq_dual!(@acc $callback [] [] $($pairs)+);
522    };
523    (@from $callback:ident [$($sa:ident),*] [$($da:ident),*]; $($pairs:tt)+) => {
524        seq_dual!(@acc $callback [$($sa),*] [$($da),*] $($pairs)+);
525    };
526}
527
528macro_rules! with_dual_col_sizes_8 {
529    ($callback:ident) => {
530        seq_dual!($callback;
531            (T0,U0) (T1,U1) (T2,U2) (T3,U3)
532            (T4,U4) (T5,U5) (T6,U6) (T7,U7)
533        );
534    };
535}
536
537#[allow(unused_macros)]
538macro_rules! with_dual_col_sizes_16 {
539    ($callback:ident) => {
540        seq_dual!(@from $callback
541            [T0,T1,T2,T3,T4,T5,T6,T7]
542            [U0,U1,U2,U3,U4,U5,U6,U7];
543            (T8,U8) (T9,U9) (T10,U10) (T11,U11)
544            (T12,U12) (T13,U13) (T14,U14) (T15,U15)
545        );
546    };
547}
548
549#[allow(unused_macros)]
550macro_rules! with_dual_col_sizes_32 {
551    ($callback:ident) => {
552        seq_dual!(@from $callback
553            [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15]
554            [U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15];
555            (T16,U16) (T17,U17) (T18,U18) (T19,U19)
556            (T20,U20) (T21,U21) (T22,U22) (T23,U23)
557            (T24,U24) (T25,U25) (T26,U26) (T27,U27)
558            (T28,U28) (T29,U29) (T30,U30) (T31,U31)
559        );
560    };
561}
562
563#[allow(unused_macros)]
564macro_rules! with_dual_col_sizes_64 {
565    ($callback:ident) => {
566        seq_dual!(@from $callback
567            [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
568             T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31]
569            [U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15,
570             U16,U17,U18,U19,U20,U21,U22,U23,U24,U25,U26,U27,U28,U29,U30,U31];
571            (T32,U32) (T33,U33) (T34,U34) (T35,U35)
572            (T36,U36) (T37,U37) (T38,U38) (T39,U39)
573            (T40,U40) (T41,U41) (T42,U42) (T43,U43)
574            (T44,U44) (T45,U45) (T46,U46) (T47,U47)
575            (T48,U48) (T49,U49) (T50,U50) (T51,U51)
576            (T52,U52) (T53,U53) (T54,U54) (T55,U55)
577            (T56,U56) (T57,U57) (T58,U58) (T59,U59)
578            (T60,U60) (T61,U61) (T62,U62) (T63,U63)
579        );
580    };
581}
582
583#[allow(unused_macros)]
584macro_rules! with_dual_col_sizes_128 {
585    ($callback:ident) => {
586        seq_dual!(@from $callback
587            [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
588             T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,
589             T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,
590             T48,T49,T50,T51,T52,T53,T54,T55,T56,T57,T58,T59,T60,T61,T62,T63]
591            [U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15,
592             U16,U17,U18,U19,U20,U21,U22,U23,U24,U25,U26,U27,U28,U29,U30,U31,
593             U32,U33,U34,U35,U36,U37,U38,U39,U40,U41,U42,U43,U44,U45,U46,U47,
594             U48,U49,U50,U51,U52,U53,U54,U55,U56,U57,U58,U59,U60,U61,U62,U63];
595            (T64,U64) (T65,U65) (T66,U66) (T67,U67)
596            (T68,U68) (T69,U69) (T70,U70) (T71,U71)
597            (T72,U72) (T73,U73) (T74,U74) (T75,U75)
598            (T76,U76) (T77,U77) (T78,U78) (T79,U79)
599            (T80,U80) (T81,U81) (T82,U82) (T83,U83)
600            (T84,U84) (T85,U85) (T86,U86) (T87,U87)
601            (T88,U88) (T89,U89) (T90,U90) (T91,U91)
602            (T92,U92) (T93,U93) (T94,U94) (T95,U95)
603            (T96,U96) (T97,U97) (T98,U98) (T99,U99)
604            (T100,U100) (T101,U101) (T102,U102) (T103,U103)
605            (T104,U104) (T105,U105) (T106,U106) (T107,U107)
606            (T108,U108) (T109,U109) (T110,U110) (T111,U111)
607            (T112,U112) (T113,U113) (T114,U114) (T115,U115)
608            (T116,U116) (T117,U117) (T118,U118) (T119,U119)
609            (T120,U120) (T121,U121) (T122,U122) (T123,U123)
610            (T124,U124) (T125,U125) (T126,U126) (T127,U127)
611        );
612    };
613}
614
615#[allow(unused_macros)]
616macro_rules! with_dual_col_sizes_200 {
617    ($callback:ident) => {
618        seq_dual!(@from $callback
619            [T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,
620             T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,
621             T32,T33,T34,T35,T36,T37,T38,T39,T40,T41,T42,T43,T44,T45,T46,T47,
622             T48,T49,T50,T51,T52,T53,T54,T55,T56,T57,T58,T59,T60,T61,T62,T63,
623             T64,T65,T66,T67,T68,T69,T70,T71,T72,T73,T74,T75,T76,T77,T78,T79,
624             T80,T81,T82,T83,T84,T85,T86,T87,T88,T89,T90,T91,T92,T93,T94,T95,
625             T96,T97,T98,T99,T100,T101,T102,T103,T104,T105,T106,T107,T108,T109,T110,T111,
626             T112,T113,T114,T115,T116,T117,T118,T119,T120,T121,T122,T123,T124,T125,T126,T127]
627            [U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,U10,U11,U12,U13,U14,U15,
628             U16,U17,U18,U19,U20,U21,U22,U23,U24,U25,U26,U27,U28,U29,U30,U31,
629             U32,U33,U34,U35,U36,U37,U38,U39,U40,U41,U42,U43,U44,U45,U46,U47,
630             U48,U49,U50,U51,U52,U53,U54,U55,U56,U57,U58,U59,U60,U61,U62,U63,
631             U64,U65,U66,U67,U68,U69,U70,U71,U72,U73,U74,U75,U76,U77,U78,U79,
632             U80,U81,U82,U83,U84,U85,U86,U87,U88,U89,U90,U91,U92,U93,U94,U95,
633             U96,U97,U98,U99,U100,U101,U102,U103,U104,U105,U106,U107,U108,U109,U110,U111,
634             U112,U113,U114,U115,U116,U117,U118,U119,U120,U121,U122,U123,U124,U125,U126,U127];
635            (T128,U128) (T129,U129) (T130,U130) (T131,U131)
636            (T132,U132) (T133,U133) (T134,U134) (T135,U135)
637            (T136,U136) (T137,U137) (T138,U138) (T139,U139)
638            (T140,U140) (T141,U141) (T142,U142) (T143,U143)
639            (T144,U144) (T145,U145) (T146,U146) (T147,U147)
640            (T148,U148) (T149,U149) (T150,U150) (T151,U151)
641            (T152,U152) (T153,U153) (T154,U154) (T155,U155)
642            (T156,U156) (T157,U157) (T158,U158) (T159,U159)
643            (T160,U160) (T161,U161) (T162,U162) (T163,U163)
644            (T164,U164) (T165,U165) (T166,U166) (T167,U167)
645            (T168,U168) (T169,U169) (T170,U170) (T171,U171)
646            (T172,U172) (T173,U173) (T174,U174) (T175,U175)
647            (T176,U176) (T177,U177) (T178,U178) (T179,U179)
648            (T180,U180) (T181,U181) (T182,U182) (T183,U183)
649            (T184,U184) (T185,U185) (T186,U186) (T187,U187)
650            (T188,U188) (T189,U189) (T190,U190) (T191,U191)
651            (T192,U192) (T193,U193) (T194,U194) (T195,U195)
652            (T196,U196) (T197,U197) (T198,U198) (T199,U199)
653        );
654    };
655}
656
657macro_rules! impl_tuple_compatible {
658    ($($T:ident),+; $($U:ident),+) => {
659        impl<$($T, $U),+> Compatible<($($U,)+)> for ($($T,)+)
660        where
661            $($T: DataType + Compatible<$U>, $U: DataType,)+
662        {}
663    };
664}
665
666macro_rules! impl_tuple_assignable {
667    ($($S:ident),+; $($D:ident),+) => {
668        impl<$($S, $D),+> Assignable<($($S,)+)> for ($($D,)+)
669        where
670            $($S: DataType, $D: DataType + Assignable<$S>,)+
671        {}
672    };
673}
674
675with_dual_col_sizes_8!(impl_tuple_compatible);
676
677#[cfg(any(
678    feature = "col16",
679    feature = "col32",
680    feature = "col64",
681    feature = "col128",
682    feature = "col200"
683))]
684with_dual_col_sizes_16!(impl_tuple_compatible);
685
686#[cfg(any(
687    feature = "col32",
688    feature = "col64",
689    feature = "col128",
690    feature = "col200"
691))]
692with_dual_col_sizes_32!(impl_tuple_compatible);
693
694#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
695with_dual_col_sizes_64!(impl_tuple_compatible);
696
697#[cfg(any(feature = "col128", feature = "col200"))]
698with_dual_col_sizes_128!(impl_tuple_compatible);
699
700#[cfg(feature = "col200")]
701with_dual_col_sizes_200!(impl_tuple_compatible);
702
703with_dual_col_sizes_8!(impl_tuple_assignable);
704
705#[cfg(any(
706    feature = "col16",
707    feature = "col32",
708    feature = "col64",
709    feature = "col128",
710    feature = "col200"
711))]
712with_dual_col_sizes_16!(impl_tuple_assignable);
713
714#[cfg(any(
715    feature = "col32",
716    feature = "col64",
717    feature = "col128",
718    feature = "col200"
719))]
720with_dual_col_sizes_32!(impl_tuple_assignable);
721
722#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
723with_dual_col_sizes_64!(impl_tuple_assignable);
724
725#[cfg(any(feature = "col128", feature = "col200"))]
726with_dual_col_sizes_128!(impl_tuple_assignable);
727
728#[cfg(feature = "col200")]
729with_dual_col_sizes_200!(impl_tuple_assignable);