use rand_chacha::ChaCha20Rng;
use rand_core::SeedableRng;
pub use rand_core::{Infallible, Rng, TryCryptoRng, TryRng};
pub trait CryptoRng: rand_core::CryptoRng {}
impl<T> CryptoRng for T where T: rand_core::CryptoRng + ?Sized {}
pub struct DeterministicRng {
inner: ChaCha20Rng,
}
impl DeterministicRng {
pub fn seed_from_u64(seed: u64) -> Self {
Self {
inner: ChaCha20Rng::seed_from_u64(seed),
}
}
pub fn seed_from_bytes(seed: &[u8; 32]) -> Self {
Self {
inner: ChaCha20Rng::from_seed(*seed),
}
}
}
impl TryRng for DeterministicRng {
type Error = core::convert::Infallible;
fn try_next_u32(&mut self) -> core::result::Result<u32, Self::Error> {
Ok(self.inner.next_u32())
}
fn try_next_u64(&mut self) -> core::result::Result<u64, Self::Error> {
Ok(self.inner.next_u64())
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> core::result::Result<(), Self::Error> {
self.inner.fill_bytes(dest);
Ok(())
}
}
impl TryCryptoRng for DeterministicRng {}
pub(crate) struct RngAdapter<'a> {
inner: &'a mut dyn CryptoRng,
}
impl<'a> RngAdapter<'a> {
pub(crate) fn new(inner: &'a mut dyn CryptoRng) -> Self {
Self { inner }
}
}
impl TryRng for RngAdapter<'_> {
type Error = Infallible;
fn try_next_u32(&mut self) -> core::result::Result<u32, Self::Error> {
Ok(self.inner.next_u32())
}
fn try_next_u64(&mut self) -> core::result::Result<u64, Self::Error> {
Ok(self.inner.next_u64())
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> core::result::Result<(), Self::Error> {
self.inner.fill_bytes(dest);
Ok(())
}
}
impl TryCryptoRng for RngAdapter<'_> {}