bolero_generator/
tuple.rs1use crate::{Driver, TypeGenerator, TypeGeneratorWithParams, TypeValueGenerator, ValueGenerator};
2
3impl TypeGenerator for () {
4 fn generate<D: Driver>(_driver: &mut D) -> Option<Self> {
5 Some(())
6 }
7}
8
9impl ValueGenerator for () {
10 type Output = ();
11
12 fn generate<D: Driver>(&self, _driver: &mut D) -> Option<Self> {
13 Some(())
14 }
15}
16
17impl TypeGeneratorWithParams for () {
18 type Output = ();
19
20 fn gen_with() -> Self::Output {}
21}
22
23macro_rules! impl_tuple {
24 ([$($acc:ident($a_value:tt),)*]) => {
25 };
27 ($head:ident($h_value:tt), $($tail:ident($t_value:tt), )* [$($acc:ident($a_value:tt),)*]) => {
28 impl<$head: TypeGenerator $(, $acc: TypeGenerator)*> TypeGenerator for ($($acc, )* $head ,) {
29 fn generate<D_: Driver>(driver: &mut D_) -> Option<Self> {
30 driver.enter_product::<Self, _, _>(|driver| {
31 Some(($(
32 $acc::generate(driver)?,
33 )* $head::generate(driver)?, ))
34 })
35 }
36
37 fn mutate<D_: Driver>(&mut self, driver: &mut D_) -> Option<()> {
38 driver.enter_product::<Self, _, _>(|driver| {
39 $(
40 self.$a_value.mutate(driver)?;
41 )*
42 self.$h_value.mutate(driver)?;
43 Some(())
44 })
45 }
46 }
47
48 impl<$head: ValueGenerator $(, $acc: ValueGenerator)*> ValueGenerator for ($($acc, )* $head ,) {
49 type Output = ($( $acc::Output, )* $head::Output, );
50
51 fn generate<D_: Driver>(&self, driver: &mut D_) -> Option<Self::Output> {
52 driver.enter_product::<Self::Output, _, _>(|driver| {
53 Some(($(
54 self.$a_value.generate(driver)?,
55 )* self.$h_value.generate(driver)?,))
56 })
57 }
58
59 fn mutate<D_: Driver>(&self, driver: &mut D_, value: &mut Self::Output) -> Option<()> {
60 driver.enter_product::<Self::Output, _, _>(|driver| {
61 $(
62 self.$a_value.mutate(driver, &mut value.$a_value)?;
63 )*
64 self.$h_value.mutate(driver, &mut value.$h_value)?;
65 Some(())
66 })
67 }
68 }
69
70 impl<$head: TypeGenerator $(, $acc: TypeGenerator)*> TypeGeneratorWithParams for ($($acc, )* $head ,) {
71 type Output = ($( TypeValueGenerator<$acc>, )* TypeValueGenerator<$head>, );
72
73 fn gen_with() -> Self::Output {
74 ($(
75 <TypeValueGenerator<$acc>>::default(),
76 )* Default::default(),)
77 }
78 }
79
80 impl_tuple!($($tail($t_value),)* [$($acc($a_value),)* $head($h_value),]);
81 };
82}
83
84impl_tuple!(
85 A(0),
86 B(1),
87 C(2),
88 D(3),
89 E(4),
90 F(5),
91 G(6),
92 H(7),
93 I(8),
94 J(9),
95 K(10),
96 L(11),
97 M(12),
98 N(13),
99 O(14),
100 P(15),
101 Q(16),
102 R(17),
103 S(18),
104 T(19),
105 U(20),
106 V(21),
107 W(22),
108 X(23),
109 Y(24),
110 Z(25),
111 AA(26),
112 AB(27),
113 AC(28),
114 AD(29),
115 AE(30),
116 AF(31),
117 AG(32),
118 []
119);
120
121#[test]
122fn tuple_type_test() {
123 let _ = generator_test!(produce::<(u8, u16, u32, u64)>());
124}
125
126#[test]
127fn tuple_gen_test() {
128 let _ = generator_test!((produce::<u8>(), produce::<u16>()));
129}
130
131#[test]
132fn tuple_with_test() {
133 let _ = generator_test!(produce::<(u8, u8)>().with());
134}