diff --git a/CHANGELOG.md b/CHANGELOG.md index 90854a3a11..76e8fd1819 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update. - Rename fns `IndexedRandom::choose_multiple` -> `sample`, `choose_multiple_array` -> `sample_array`, `choose_multiple_weighted` -> `sample_weighted`, struct `SliceChooseIter` -> `IndexedSamples` and fns `IteratorRandom::choose_multiple` -> `sample`, `choose_multiple_fill` -> `sample_fill` (#1632) - Use Edition 2024 and MSRV 1.85 (#1653) - Let `Fill` be implemented for element types, not sliceable types (#1652) +- Replace fn `TryRngCore::read_adapter(..) -> RngReadAdapter` with simpler struct `RngReader` (#1669) ### Additions - Add fns `IndexedRandom::choose_iter`, `choose_weighted_iter` (#1632) diff --git a/rand_core/CHANGELOG.md b/rand_core/CHANGELOG.md index 4ec608a360..84c40cf9aa 100644 --- a/rand_core/CHANGELOG.md +++ b/rand_core/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Relax `Sized` bound on impls of `SeedableRng` (#1641) - Move `rand_core::impls::*` to `rand_core::le` module (#1667) - Use Edition 2024 and MSRV 1.85 (#1668) +- Remove fn `TryRngCore::read_adapter(..) -> RngReadAdapter` (replaced with `rand::RngReader`) (#1669) ## [0.9.3] — 2025-02-29 ### Other diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs index 5efe32f578..a0f30fc8d4 100644 --- a/rand_core/src/lib.rs +++ b/rand_core/src/lib.rs @@ -207,15 +207,6 @@ pub trait TryRngCore { fn unwrap_mut(&mut self) -> UnwrapMut<'_, Self> { UnwrapMut(self) } - - /// Convert an [`RngCore`] to a [`RngReadAdapter`]. - #[cfg(feature = "std")] - fn read_adapter(&mut self) -> RngReadAdapter<'_, Self> - where - Self: Sized, - { - RngReadAdapter { inner: self } - } } // Note that, unfortunately, this blanket impl prevents us from implementing @@ -543,40 +534,6 @@ pub trait SeedableRng: Sized { } } -/// Adapter that enables reading through a [`io::Read`](std::io::Read) from a [`RngCore`]. -/// -/// # Examples -/// -/// ```no_run -/// # use std::{io, io::Read}; -/// # use std::fs::File; -/// # use rand_core::{OsRng, TryRngCore}; -/// -/// io::copy(&mut OsRng.read_adapter().take(100), &mut File::create("/tmp/random.bytes").unwrap()).unwrap(); -/// ``` -#[cfg(feature = "std")] -pub struct RngReadAdapter<'a, R: TryRngCore + ?Sized> { - inner: &'a mut R, -} - -#[cfg(feature = "std")] -impl std::io::Read for RngReadAdapter<'_, R> { - #[inline] - fn read(&mut self, buf: &mut [u8]) -> Result { - self.inner - .try_fill_bytes(buf) - .map_err(|err| std::io::Error::other(std::format!("RNG error: {err}")))?; - Ok(buf.len()) - } -} - -#[cfg(feature = "std")] -impl std::fmt::Debug for RngReadAdapter<'_, R> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ReadAdapter").finish() - } -} - #[cfg(test)] mod test { use super::*; diff --git a/src/lib.rs b/src/lib.rs index d66ea9333a..3ae859eed4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,6 +129,41 @@ pub use rng::{Fill, Rng}; #[cfg(feature = "thread_rng")] use crate::distr::{Distribution, StandardUniform}; +/// Adapter to support [`std::io::Read`] over a [`TryRngCore`] +/// +/// # Examples +/// +/// ```no_run +/// use std::{io, io::Read}; +/// use std::fs::File; +/// use rand::{rngs::OsRng, RngReader}; +/// +/// io::copy( +/// &mut RngReader(OsRng).take(100), +/// &mut File::create("/tmp/random.bytes").unwrap() +/// ).unwrap(); +/// ``` +#[cfg(feature = "std")] +pub struct RngReader(pub R); + +#[cfg(feature = "std")] +impl std::io::Read for RngReader { + #[inline] + fn read(&mut self, buf: &mut [u8]) -> Result { + self.0 + .try_fill_bytes(buf) + .map_err(|err| std::io::Error::other(std::format!("RNG error: {err}")))?; + Ok(buf.len()) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for RngReader { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("RngReader").finish() + } +} + /// Generate a random value using the thread-local random number generator. /// /// This function is shorthand for [rng()].[random()](Rng::random): @@ -337,6 +372,24 @@ mod test { } } + #[cfg(feature = "std")] + #[test] + fn rng_reader() { + use std::io::Read; + + let mut rng = StepRng(255, 1); + let mut buf = [0u8; 24]; + let expected = [ + 255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, + ]; + + RngReader(&mut rng).read_exact(&mut buf).unwrap(); + assert_eq!(&buf, &expected); + + RngReader(StepRng(255, 1)).read_exact(&mut buf).unwrap(); + assert_eq!(&buf, &expected); + } + #[test] #[cfg(feature = "thread_rng")] fn test_random() {