use rand_core::{CryptoRng, RngCore};
use crate::utils::cell::RefCell;
use crate::utils::init::{init, Init};
use crate::utils::sync::blocking::Mutex;
pub struct SharedRand<T> {
shared: Mutex<RefCell<T>>,
}
impl<T> SharedRand<T> {
pub const fn new(rand: T) -> Self {
Self {
shared: Mutex::new(RefCell::new(rand)),
}
}
pub fn init(rand: impl Init<T>) -> impl Init<Self> {
init!(Self {
shared <- Mutex::init(RefCell::init(rand)),
})
}
}
impl<T> rand_core::RngCore for &SharedRand<T>
where
T: rand_core::RngCore,
{
fn next_u32(&mut self) -> u32 {
self.shared.lock(|rand| rand.borrow_mut().next_u32())
}
fn next_u64(&mut self) -> u64 {
self.shared.lock(|rand| rand.borrow_mut().next_u64())
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.shared.lock(|rand| rand.borrow_mut().fill_bytes(dest))
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
self.shared
.lock(|rand| rand.borrow_mut().try_fill_bytes(dest))
}
}
impl<T> CryptoRng for &SharedRand<T> where T: CryptoRng {}
pub struct WeakTestOnlyRand(u32);
impl WeakTestOnlyRand {
const SEED: u32 = 2463534242;
pub const fn new_default() -> Self {
Self(Self::SEED)
}
pub const fn new(seed: u32) -> Self {
Self(seed)
}
}
impl RngCore for WeakTestOnlyRand {
fn next_u32(&mut self) -> u32 {
self.0 = self.0 ^ (self.0 << 13);
self.0 = self.0 ^ (self.0 >> 17);
self.0 = self.0 ^ (self.0 << 5);
self.0
}
fn next_u64(&mut self) -> u64 {
rand_core::impls::next_u64_via_u32(self)
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
rand_core::impls::fill_bytes_via_next(self, dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
rand_core::impls::fill_bytes_via_next(self, dest);
Ok(())
}
}
impl CryptoRng for WeakTestOnlyRand {}