1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use crate::{Driver, TypeGenerator, TypeGeneratorWithParams, TypeValueGenerator, ValueGenerator};

impl TypeGenerator for () {
    fn generate<D: Driver>(_driver: &mut D) -> Option<Self> {
        Some(())
    }
}

impl ValueGenerator for () {
    type Output = ();

    fn generate<D: Driver>(&self, _driver: &mut D) -> Option<Self> {
        Some(())
    }
}

impl TypeGeneratorWithParams for () {
    type Output = ();

    fn gen_with() -> Self::Output {}
}

macro_rules! impl_tuple {
    ([$($acc:ident($a_value:tt),)*]) => {
        // done
    };
    ($head:ident($h_value:tt), $($tail:ident($t_value:tt), )* [$($acc:ident($a_value:tt),)*]) => {
        impl<$head: TypeGenerator $(, $acc: TypeGenerator)*> TypeGenerator for ($($acc, )* $head ,) {
            fn generate<D_: Driver>(driver: &mut D_) -> Option<Self> {
                Some(($(
                    $acc::generate(driver)?,
                )* $head::generate(driver)?, ))
            }

            fn mutate<D_: Driver>(&mut self, driver: &mut D_) -> Option<()> {
                $(
                    self.$a_value.mutate(driver)?;
                )*
                self.$h_value.mutate(driver)?;
                Some(())
            }
        }

        impl<$head: ValueGenerator $(, $acc: ValueGenerator)*> ValueGenerator for ($($acc, )* $head ,) {
            type Output = ($( $acc::Output, )* $head::Output, );

            fn generate<D_: Driver>(&self, driver: &mut D_) -> Option<Self::Output> {
                Some(($(
                    self.$a_value.generate(driver)?,
                )* self.$h_value.generate(driver)?,))
            }

            fn mutate<D_: Driver>(&self, driver: &mut D_, value: &mut Self::Output) -> Option<()> {
                $(
                    self.$a_value.mutate(driver, &mut value.$a_value)?;
                )*
                self.$h_value.mutate(driver, &mut value.$h_value)?;
                Some(())
            }
        }

        impl<$head: TypeGenerator $(, $acc: TypeGenerator)*> TypeGeneratorWithParams for ($($acc, )* $head ,) {
            type Output = ($( TypeValueGenerator<$acc>, )* TypeValueGenerator<$head>, );

            fn gen_with() -> Self::Output {
                ($(
                    <TypeValueGenerator<$acc>>::default(),
                )* Default::default(),)
            }
        }

        impl_tuple!($($tail($t_value),)* [$($acc($a_value),)* $head($h_value),]);
    };
}

impl_tuple!(
    A(0),
    B(1),
    C(2),
    D(3),
    E(4),
    F(5),
    G(6),
    H(7),
    I(8),
    J(9),
    K(10),
    L(11),
    M(12),
    N(13),
    O(14),
    P(15),
    Q(16),
    R(17),
    S(18),
    T(19),
    U(20),
    V(21),
    W(22),
    X(23),
    Y(24),
    Z(25),
    AA(26),
    AB(27),
    AC(28),
    AD(29),
    AE(30),
    AF(31),
    AG(32),
    []
);

#[test]
fn tuple_type_test() {
    let _ = generator_test!(gen::<(u8, u16, u32, u64)>());
}

#[test]
fn tuple_gen_test() {
    let _ = generator_test!((gen::<u8>(), gen::<u16>()));
}

#[test]
fn tuple_with_test() {
    let _ = generator_test!(gen::<(u8, u8)>().with());
}