Skip to content

Commit d0eef34

Browse files
authored
Move fn read_adapter out of trait TryRngCore to rand (#1669)
2 parents 140a6d4 + 26ffd25 commit d0eef34

File tree

4 files changed

+55
-43
lines changed

4 files changed

+55
-43
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
1414
- 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)
1515
- Use Edition 2024 and MSRV 1.85 (#1653)
1616
- Let `Fill` be implemented for element types, not sliceable types (#1652)
17+
- Replace fn `TryRngCore::read_adapter(..) -> RngReadAdapter` with simpler struct `RngReader` (#1669)
1718

1819
### Additions
1920
- Add fns `IndexedRandom::choose_iter`, `choose_weighted_iter` (#1632)

rand_core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
- Relax `Sized` bound on impls of `SeedableRng` (#1641)
1010
- Move `rand_core::impls::*` to `rand_core::le` module (#1667)
1111
- Use Edition 2024 and MSRV 1.85 (#1668)
12+
- Remove fn `TryRngCore::read_adapter(..) -> RngReadAdapter` (replaced with `rand::RngReader`) (#1669)
1213

1314
## [0.9.3] — 2025-02-29
1415
### Other

rand_core/src/lib.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -207,15 +207,6 @@ pub trait TryRngCore {
207207
fn unwrap_mut(&mut self) -> UnwrapMut<'_, Self> {
208208
UnwrapMut(self)
209209
}
210-
211-
/// Convert an [`RngCore`] to a [`RngReadAdapter`].
212-
#[cfg(feature = "std")]
213-
fn read_adapter(&mut self) -> RngReadAdapter<'_, Self>
214-
where
215-
Self: Sized,
216-
{
217-
RngReadAdapter { inner: self }
218-
}
219210
}
220211

221212
// Note that, unfortunately, this blanket impl prevents us from implementing
@@ -543,40 +534,6 @@ pub trait SeedableRng: Sized {
543534
}
544535
}
545536

546-
/// Adapter that enables reading through a [`io::Read`](std::io::Read) from a [`RngCore`].
547-
///
548-
/// # Examples
549-
///
550-
/// ```no_run
551-
/// # use std::{io, io::Read};
552-
/// # use std::fs::File;
553-
/// # use rand_core::{OsRng, TryRngCore};
554-
///
555-
/// io::copy(&mut OsRng.read_adapter().take(100), &mut File::create("/tmp/random.bytes").unwrap()).unwrap();
556-
/// ```
557-
#[cfg(feature = "std")]
558-
pub struct RngReadAdapter<'a, R: TryRngCore + ?Sized> {
559-
inner: &'a mut R,
560-
}
561-
562-
#[cfg(feature = "std")]
563-
impl<R: TryRngCore + ?Sized> std::io::Read for RngReadAdapter<'_, R> {
564-
#[inline]
565-
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
566-
self.inner
567-
.try_fill_bytes(buf)
568-
.map_err(|err| std::io::Error::other(std::format!("RNG error: {err}")))?;
569-
Ok(buf.len())
570-
}
571-
}
572-
573-
#[cfg(feature = "std")]
574-
impl<R: TryRngCore + ?Sized> std::fmt::Debug for RngReadAdapter<'_, R> {
575-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
576-
f.debug_struct("ReadAdapter").finish()
577-
}
578-
}
579-
580537
#[cfg(test)]
581538
mod test {
582539
use super::*;

src/lib.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,41 @@ pub use rng::{Fill, Rng};
129129
#[cfg(feature = "thread_rng")]
130130
use crate::distr::{Distribution, StandardUniform};
131131

132+
/// Adapter to support [`std::io::Read`] over a [`TryRngCore`]
133+
///
134+
/// # Examples
135+
///
136+
/// ```no_run
137+
/// use std::{io, io::Read};
138+
/// use std::fs::File;
139+
/// use rand::{rngs::OsRng, RngReader};
140+
///
141+
/// io::copy(
142+
/// &mut RngReader(OsRng).take(100),
143+
/// &mut File::create("/tmp/random.bytes").unwrap()
144+
/// ).unwrap();
145+
/// ```
146+
#[cfg(feature = "std")]
147+
pub struct RngReader<R: TryRngCore>(pub R);
148+
149+
#[cfg(feature = "std")]
150+
impl<R: TryRngCore> std::io::Read for RngReader<R> {
151+
#[inline]
152+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
153+
self.0
154+
.try_fill_bytes(buf)
155+
.map_err(|err| std::io::Error::other(std::format!("RNG error: {err}")))?;
156+
Ok(buf.len())
157+
}
158+
}
159+
160+
#[cfg(feature = "std")]
161+
impl<R: TryRngCore> std::fmt::Debug for RngReader<R> {
162+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163+
f.debug_tuple("RngReader").finish()
164+
}
165+
}
166+
132167
/// Generate a random value using the thread-local random number generator.
133168
///
134169
/// This function is shorthand for <code>[rng()].[random()](Rng::random)</code>:
@@ -337,6 +372,24 @@ mod test {
337372
}
338373
}
339374

375+
#[cfg(feature = "std")]
376+
#[test]
377+
fn rng_reader() {
378+
use std::io::Read;
379+
380+
let mut rng = StepRng(255, 1);
381+
let mut buf = [0u8; 24];
382+
let expected = [
383+
255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
384+
];
385+
386+
RngReader(&mut rng).read_exact(&mut buf).unwrap();
387+
assert_eq!(&buf, &expected);
388+
389+
RngReader(StepRng(255, 1)).read_exact(&mut buf).unwrap();
390+
assert_eq!(&buf, &expected);
391+
}
392+
340393
#[test]
341394
#[cfg(feature = "thread_rng")]
342395
fn test_random() {

0 commit comments

Comments
 (0)