Add read_adapter to avoid dynamic dispatch (#1267)
* Add read_adapter to avoid dynamic dispatch * Get rid of the dyn Read impl since we can't deprecate it
This commit is contained in:
parent
50b9a44741
commit
0dddc2c559
@ -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;
|
||||
@ -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`]
|
||||
@ -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 {}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user