use rand::{rngs::SmallRng, RngCore, SeedableRng};
use std::{cell::RefCell, marker::PhantomData};
crate::user_const! {
const RNG_SEED: u64 = 69_420;
}
thread_local! {
static THREAD_RNG: RefCell<SmallRng> = RefCell::new(SmallRng::seed_from_u64(*RNG_SEED));
}
#[derive(Clone, Copy, Debug, Default)]
pub struct FartThreadRng {
pub(crate) no_send: PhantomData<*mut ()>,
}
impl RngCore for FartThreadRng {
fn next_u32(&mut self) -> u32 {
THREAD_RNG.with(|rng| {
let mut rng = rng.borrow_mut();
rng.next_u32()
})
}
fn next_u64(&mut self) -> u64 {
THREAD_RNG.with(|rng| {
let mut rng = rng.borrow_mut();
rng.next_u64()
})
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
THREAD_RNG.with(|rng| {
let mut rng = rng.borrow_mut();
rng.fill_bytes(dest)
})
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> std::result::Result<(), rand::Error> {
THREAD_RNG.with(|rng| {
let mut rng = rng.borrow_mut();
rng.try_fill_bytes(dest)
})
}
}
#[cfg(test)]
mod tests {
use super::FartThreadRng;
#[test]
fn fart_thread_rng_impls_rng() {
fn impls_rng(_rng: impl rand::Rng) {}
impls_rng(FartThreadRng::default());
}
}