use rand::rngs::StdRng;
use rand::{RngCore, SeedableRng};
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 RngCore for HegelRandom {
fn next_u32(&mut self) -> u32 {
match self {
Self::ArtificialRandom(tc) => integers().do_draw(tc),
Self::TrueRandom(rng) => rng.next_u32(),
}
}
fn next_u64(&mut self) -> u64 {
match self {
Self::ArtificialRandom(tc) => integers().do_draw(tc),
Self::TrueRandom(rng) => rng.next_u64(),
}
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
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),
}
}
}
pub fn randoms() -> RandomsGenerator {
RandomsGenerator {
use_true_random: false,
}
}