use std::convert::Infallible;
use rand::Rng;
use rand::SeedableRng;
use rand::rand_core::TryRng;
use rand::rngs::StdRng;
use super::{Generator, TestCase, binary, integers};
pub struct RandomsGenerator {
use_true_random: bool,
}
impl RandomsGenerator {
pub fn use_true_random(mut self, use_true_random: bool) -> Self {
self.use_true_random = use_true_random;
self
}
}
impl Generator<HegelRandom> for RandomsGenerator {
fn do_draw(&self, tc: &TestCase) -> HegelRandom {
if self.use_true_random {
let seed: u64 = integers().do_draw(tc);
HegelRandom::TrueRandom(Box::new(StdRng::seed_from_u64(seed)))
} else {
HegelRandom::ArtificialRandom(tc.clone())
}
}
}
#[derive(Debug)]
pub enum HegelRandom {
ArtificialRandom(TestCase),
TrueRandom(Box<StdRng>),
}
impl TryRng for HegelRandom {
type Error = Infallible;
fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
Ok(match self {
Self::ArtificialRandom(tc) => integers().do_draw(tc),
Self::TrueRandom(rng) => rng.next_u32(),
})
}
fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
Ok(match self {
Self::ArtificialRandom(tc) => integers().do_draw(tc),
Self::TrueRandom(rng) => rng.next_u64(),
})
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
match self {
Self::ArtificialRandom(tc) => {
let bytes: Vec<u8> = binary()
.min_size(dest.len())
.max_size(dest.len())
.do_draw(tc);
dest.copy_from_slice(&bytes);
}
Self::TrueRandom(rng) => rng.fill_bytes(dest),
}
Ok(())
}
}
pub fn randoms() -> RandomsGenerator {
RandomsGenerator {
use_true_random: false,
}
}