pub use generate_random_macro::GenerateRandom;
pub trait GenerateRandom {
fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self;
}
macro_rules! impl_generate_random {
( $( $t:ty, )+ ) => {
$(
impl GenerateRandom for $t {
fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self {
rng.gen()
}
}
)+
}
}
impl_generate_random! {
bool,
char,
u8,
i8,
u16,
i16,
u32,
i32,
u64,
i64,
u128,
i128,
usize,
isize,
f32,
f64,
}
impl<T: GenerateRandom> GenerateRandom for Option<T> {
fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self {
if bool::generate_random(rng) {
Some(T::generate_random(rng))
} else {
None
}
}
}
macro_rules! impl_generate_random_tuple {
( $t0:ident $( $t:ident )* ) => {
impl< $t0, $( $t, )* > GenerateRandom for ( $t0, $( $t, )* )
where
$t0: GenerateRandom,
$(
$t: GenerateRandom,
)*
{
fn generate_random<R: rand::Rng + ?Sized>(rng: &mut R) -> Self {
(
$t0::generate_random(rng),
$(
$t::generate_random(rng),
)*
)
}
}
impl_generate_random_tuple!( $( $t )* );
};
() => {
impl GenerateRandom for () {
fn generate_random<R: rand::Rng + ?Sized>(_rng: &mut R) -> Self {
()
}
}
}
}
impl_generate_random_tuple!(A B C D E F G H I J K L);
#[cfg(test)]
mod tests {
use super::*;
fn rng() -> impl rand::Rng {
use rand::SeedableRng;
rand_chacha::ChaCha8Rng::from(rand_chacha::ChaCha8Core::from_seed([37; 32]))
}
#[test]
fn test_u8() {
let mut rng = rng();
assert_eq!(u8::generate_random(&mut rng), 55);
}
}