use std::fmt::Debug;
#[derive(Clone, Default)]
pub(crate) enum Rnd {
#[default]
Real,
#[cfg(test)]
Test(std::sync::Arc<dyn Fn() -> f64 + Send + Sync>),
}
impl Debug for Rnd {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Real => write!(f, "Real"),
#[cfg(test)]
Self::Test(_) => write!(f, "Test"),
}
}
}
impl Rnd {
#[cfg(test)]
pub fn new_fixed(value: f64) -> Self {
Self::Test(std::sync::Arc::new(move || value))
}
#[cfg(test)]
pub fn new_function<F>(f: F) -> Self
where
F: Fn() -> f64 + Send + Sync + 'static,
{
Self::Test(std::sync::Arc::new(f))
}
#[cfg_attr(test, mutants::skip)] pub fn next_f64(&self) -> f64 {
match self {
Self::Real => fastrand::f64(),
#[cfg(test)]
Self::Test(generator) => generator(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn debug_real() {
assert_eq!(format!("{:?}", Rnd::Real), "Real");
}
#[test]
fn debug_test() {
assert_eq!(format!("{:?}", Rnd::new_fixed(0.5)), "Test");
}
}