use cfg_if::cfg_if;
use crate::csprng::Csprng;
#[derive(Copy, Clone, Debug, Default)]
pub struct Rng;
impl Rng {
#[inline]
pub const fn new() -> Self {
Self
}
}
impl Csprng for Rng {
fn fill_bytes(&self, dst: &mut [u8]) {
cfg_if! {
if #[cfg(feature = "trng")] {
crate::csprng::trng::thread_rng().fill_bytes(dst)
} else if #[cfg(feature = "getrandom")] {
getrandom::fill(dst).expect("should not fail")
} else {
unsafe extern "C" {
unsafe fn crypto_getrandom(dst: *mut u8, len: usize);
}
unsafe {
crypto_getrandom(dst.as_mut_ptr(), dst.len())
}
}
}
}
}
#[cfg(feature = "rand_compat")]
impl rand_core::TryCryptoRng for Rng {}
#[cfg(feature = "rand_compat")]
impl rand_core::TryRng for Rng {
type Error = core::convert::Infallible;
fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
rand_core::utils::next_word_via_fill(self)
}
fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
rand_core::utils::next_word_via_fill(self)
}
fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error> {
Csprng::fill_bytes(self, dst);
Ok(())
}
}