Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
use core::convert::AsMut;
use core::default::Default;

#[cfg(feature = "std")] extern crate std;
#[cfg(feature = "alloc")] extern crate alloc;
#[cfg(feature = "std")] extern crate std;
#[cfg(feature = "alloc")] use alloc::boxed::Box;

pub use error::Error;
Expand Down Expand Up @@ -182,6 +182,13 @@ pub trait RngCore {
/// `fill_bytes` may be implemented with
/// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;

/// Convert an [`RngCore`] to a [`RngReadAdapter`].
#[cfg(feature = "std")]
fn read_adapter(&mut self) -> RngReadAdapter<'_, Self>
where Self: Sized {
RngReadAdapter { inner: self }
}
}

/// A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`]
Expand Down Expand Up @@ -469,14 +476,37 @@ impl<R: RngCore + ?Sized> RngCore for Box<R> {
}
}

/// Adapter that enables reading through a [`io::Read`](std::io::Read) from a [`RngCore`].
///
/// # Examples
///
/// ```rust
/// # use std::{io, io::Read};
/// # use std::fs::File;
/// # use rand_core::{OsRng, RngCore};
///
/// io::copy(&mut OsRng.read_adapter().take(100), &mut File::create("/tmp/random.bytes").unwrap()).unwrap();
/// ```
#[cfg(feature = "std")]
impl std::io::Read for dyn RngCore {
pub struct RngReadAdapter<'a, R: RngCore + ?Sized> {
inner: &'a mut R,
}

#[cfg(feature = "std")]
impl<R: RngCore + ?Sized> std::io::Read for RngReadAdapter<'_, R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
self.try_fill_bytes(buf)?;
self.inner.try_fill_bytes(buf)?;
Ok(buf.len())
}
}

#[cfg(feature = "std")]
impl<R: RngCore + ?Sized> std::fmt::Debug for RngReadAdapter<'_, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ReadAdapter").finish()
}
}

// Implement `CryptoRng` for references to a `CryptoRng`.
impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}

Expand Down