bolero_generator/
tuple.rs

1use 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        // done
26    };
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}