1pub use generate_random_macro::GenerateRandom;
34
35pub trait GenerateRandom {
40 fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self;
42}
43
44macro_rules! impl_generate_random {
45 ( $( $t:ty, )+ ) => {
46 $(
47 impl GenerateRandom for $t {
48 fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self {
49 rng.gen()
50 }
51 }
52 )+
53 }
54}
55
56impl_generate_random! {
57 bool,
58 char,
59 u8,
60 i8,
61 u16,
62 i16,
63 u32,
64 i32,
65 u64,
66 i64,
67 u128,
68 i128,
69 usize,
70 isize,
71 f32,
72 f64,
73}
74
75impl<T: GenerateRandom> GenerateRandom for Option<T> {
76 fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self {
77 if bool::generate_random(rng) {
78 Some(T::generate_random(rng))
79 } else {
80 None
81 }
82 }
83}
84
85macro_rules! impl_generate_random_tuple {
86 ( $t0:ident $( $t:ident )* ) => {
87 impl< $t0, $( $t, )* > GenerateRandom for ( $t0, $( $t, )* )
88 where
89 $t0: GenerateRandom,
90 $(
91 $t: GenerateRandom,
92 )*
93 {
94 fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self {
95 (
96 $t0::generate_random(rng),
97 $(
98 $t::generate_random(rng),
99 )*
100 )
101 }
102 }
103 impl_generate_random_tuple!( $( $t )* );
104 };
105 () => {
106 impl GenerateRandom for () {
107 fn generate_random<R: rand::Rng + ?Sized>(_rng: &mut R) -> Self {
108 ()
109 }
110 }
111 }
112}
113
114impl_generate_random_tuple!(A B C D E F G H I J K L);
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 fn rng() -> impl rand::Rng {
121 use rand::SeedableRng;
122 rand_chacha::ChaCha8Rng::from(rand_chacha::ChaCha8Core::from_seed([37; 32]))
123 }
124
125 #[test]
126 fn test_u8() {
127 let mut rng = rng();
128 assert_eq!(u8::generate_random(&mut rng), 55);
129 }
130}