1use super::{BasicGenerator, DefaultGenerator, Generator, TestCase, labels};
2use crate::cbor_utils::{cbor_array, cbor_map};
3use ciborium::Value;
4use std::marker::PhantomData;
5
6#[macro_export]
27macro_rules! tuples {
28 () => {
29 $crate::generators::tuples0()
30 };
31 ($g1:expr $(,)?) => {
32 $crate::generators::tuples1($g1)
33 };
34 ($g1:expr, $g2:expr $(,)?) => {
35 $crate::generators::tuples2($g1, $g2)
36 };
37 ($g1:expr, $g2:expr, $g3:expr $(,)?) => {
38 $crate::generators::tuples3($g1, $g2, $g3)
39 };
40 ($g1:expr, $g2:expr, $g3:expr, $g4:expr $(,)?) => {
41 $crate::generators::tuples4($g1, $g2, $g3, $g4)
42 };
43 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr $(,)?) => {
44 $crate::generators::tuples5($g1, $g2, $g3, $g4, $g5)
45 };
46 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr, $g6:expr $(,)?) => {
47 $crate::generators::tuples6($g1, $g2, $g3, $g4, $g5, $g6)
48 };
49 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr, $g6:expr, $g7:expr $(,)?) => {
50 $crate::generators::tuples7($g1, $g2, $g3, $g4, $g5, $g6, $g7)
51 };
52 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr, $g6:expr, $g7:expr, $g8:expr $(,)?) => {
53 $crate::generators::tuples8($g1, $g2, $g3, $g4, $g5, $g6, $g7, $g8)
54 };
55 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr, $g6:expr, $g7:expr, $g8:expr, $g9:expr $(,)?) => {
56 $crate::generators::tuples9($g1, $g2, $g3, $g4, $g5, $g6, $g7, $g8, $g9)
57 };
58 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr, $g6:expr, $g7:expr, $g8:expr, $g9:expr, $g10:expr $(,)?) => {
59 $crate::generators::tuples10($g1, $g2, $g3, $g4, $g5, $g6, $g7, $g8, $g9, $g10)
60 };
61 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr, $g6:expr, $g7:expr, $g8:expr, $g9:expr, $g10:expr, $g11:expr $(,)?) => {
62 $crate::generators::tuples11($g1, $g2, $g3, $g4, $g5, $g6, $g7, $g8, $g9, $g10, $g11)
63 };
64 ($g1:expr, $g2:expr, $g3:expr, $g4:expr, $g5:expr, $g6:expr, $g7:expr, $g8:expr, $g9:expr, $g10:expr, $g11:expr, $g12:expr $(,)?) => {
65 $crate::generators::tuples12(
66 $g1, $g2, $g3, $g4, $g5, $g6, $g7, $g8, $g9, $g10, $g11, $g12,
67 )
68 };
69}
70
71macro_rules! impl_tuple {
72 ($name:ident, $fn_name:ident, $(($idx:tt, $field:ident, $G:ident, $T:ident)),+) => {
73 pub struct $name<$($G,)+ $($T,)+> {
74 $($field: $G,)+
75 _phantom: PhantomData<fn($($T,)+)>,
76 }
77
78 impl<$($T,)+ $($G,)+> Generator<($($T,)+)> for $name<$($G,)+ $($T,)+>
79 where
80 $($G: Generator<$T>,)+
81 {
82 fn do_draw(&self, tc: &TestCase) -> ($($T,)+) {
83 if let Some(basic) = self.as_basic() {
84 basic.do_draw(tc)
85 } else {
86 tc.start_span(labels::TUPLE);
88 let result = ($(self.$field.do_draw(tc),)+);
89 tc.stop_span(false);
90 result
91 }
93 }
94
95 fn as_basic(&self) -> Option<BasicGenerator<'_, ($($T,)+)>> {
96 $(let $field = self.$field.as_basic()?;)+
97
98 let schema = cbor_map! {
99 "type" => "tuple",
100 "elements" => cbor_array![$($field.schema().clone()),+]
101 };
102
103 Some(BasicGenerator::new(schema, move |raw| {
104 let arr = match raw {
105 Value::Array(arr) => arr,
106 _ => panic!("Expected array from tuple schema, got {:?}", raw), };
108 let mut iter = arr.into_iter();
109
110 ($($field.parse_raw(iter.next().expect(concat!("tuple missing element ", stringify!($idx)))),)+)
111 }))
112 }
113 }
114
115 #[doc(hidden)]
116 #[allow(clippy::too_many_arguments)]
117 pub fn $fn_name<$($T,)+ $($G: Generator<$T>,)+>(
118 $($field: $G,)+
119 ) -> $name<$($G,)+ $($T,)+> {
120 $name {
121 $($field,)+
122 _phantom: PhantomData,
123 }
124 }
125
126 impl<$($T: DefaultGenerator + 'static,)+> DefaultGenerator for ($($T,)+)
127 where
128 $(<$T as DefaultGenerator>::Generator: Send + Sync,)+
129 {
130 type Generator = $name<$(<$T as DefaultGenerator>::Generator,)+ $($T,)+>;
131 fn default_generator() -> Self::Generator {
132 $fn_name($(<$T>::default_generator(),)+)
133 }
134 }
135 };
136}
137
138pub struct Tuple0Generator;
140
141impl Generator<()> for Tuple0Generator {
142 fn do_draw(&self, _tc: &TestCase) {}
143}
144
145#[doc(hidden)]
146pub fn tuples0() -> Tuple0Generator {
147 Tuple0Generator
148}
149
150impl DefaultGenerator for () {
151 type Generator = Tuple0Generator;
152 fn default_generator() -> Self::Generator {
153 tuples0()
154 }
155}
156
157impl_tuple!(Tuple1Generator, tuples1, (0, gen1, G1, T1));
158impl_tuple!(
159 Tuple2Generator,
160 tuples2,
161 (0, gen1, G1, T1),
162 (1, gen2, G2, T2)
163);
164impl_tuple!(
165 Tuple3Generator,
166 tuples3,
167 (0, gen1, G1, T1),
168 (1, gen2, G2, T2),
169 (2, gen3, G3, T3)
170);
171impl_tuple!(
172 Tuple4Generator,
173 tuples4,
174 (0, gen1, G1, T1),
175 (1, gen2, G2, T2),
176 (2, gen3, G3, T3),
177 (3, gen4, G4, T4)
178);
179impl_tuple!(
180 Tuple5Generator,
181 tuples5,
182 (0, gen1, G1, T1),
183 (1, gen2, G2, T2),
184 (2, gen3, G3, T3),
185 (3, gen4, G4, T4),
186 (4, gen5, G5, T5)
187);
188impl_tuple!(
189 Tuple6Generator,
190 tuples6,
191 (0, gen1, G1, T1),
192 (1, gen2, G2, T2),
193 (2, gen3, G3, T3),
194 (3, gen4, G4, T4),
195 (4, gen5, G5, T5),
196 (5, gen6, G6, T6)
197);
198impl_tuple!(
199 Tuple7Generator,
200 tuples7,
201 (0, gen1, G1, T1),
202 (1, gen2, G2, T2),
203 (2, gen3, G3, T3),
204 (3, gen4, G4, T4),
205 (4, gen5, G5, T5),
206 (5, gen6, G6, T6),
207 (6, gen7, G7, T7)
208);
209impl_tuple!(
210 Tuple8Generator,
211 tuples8,
212 (0, gen1, G1, T1),
213 (1, gen2, G2, T2),
214 (2, gen3, G3, T3),
215 (3, gen4, G4, T4),
216 (4, gen5, G5, T5),
217 (5, gen6, G6, T6),
218 (6, gen7, G7, T7),
219 (7, gen8, G8, T8)
220);
221impl_tuple!(
222 Tuple9Generator,
223 tuples9,
224 (0, gen1, G1, T1),
225 (1, gen2, G2, T2),
226 (2, gen3, G3, T3),
227 (3, gen4, G4, T4),
228 (4, gen5, G5, T5),
229 (5, gen6, G6, T6),
230 (6, gen7, G7, T7),
231 (7, gen8, G8, T8),
232 (8, gen9, G9, T9)
233);
234impl_tuple!(
235 Tuple10Generator,
236 tuples10,
237 (0, gen1, G1, T1),
238 (1, gen2, G2, T2),
239 (2, gen3, G3, T3),
240 (3, gen4, G4, T4),
241 (4, gen5, G5, T5),
242 (5, gen6, G6, T6),
243 (6, gen7, G7, T7),
244 (7, gen8, G8, T8),
245 (8, gen9, G9, T9),
246 (9, gen10, G10, T10)
247);
248impl_tuple!(
249 Tuple11Generator,
250 tuples11,
251 (0, gen1, G1, T1),
252 (1, gen2, G2, T2),
253 (2, gen3, G3, T3),
254 (3, gen4, G4, T4),
255 (4, gen5, G5, T5),
256 (5, gen6, G6, T6),
257 (6, gen7, G7, T7),
258 (7, gen8, G8, T8),
259 (8, gen9, G9, T9),
260 (9, gen10, G10, T10),
261 (10, gen11, G11, T11)
262);
263impl_tuple!(
264 Tuple12Generator,
265 tuples12,
266 (0, gen1, G1, T1),
267 (1, gen2, G2, T2),
268 (2, gen3, G3, T3),
269 (3, gen4, G4, T4),
270 (4, gen5, G5, T5),
271 (5, gen6, G6, T6),
272 (6, gen7, G7, T7),
273 (7, gen8, G8, T8),
274 (8, gen9, G9, T9),
275 (9, gen10, G10, T10),
276 (10, gen11, G11, T11),
277 (11, gen12, G12, T12)
278);