1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

shuf: adapt to API changes of rand

This commit is contained in:
Daniel Hofstetter 2025-01-30 09:09:12 +01:00
parent 14ce43fe52
commit 527602248f
2 changed files with 14 additions and 24 deletions

View file

@ -16,7 +16,7 @@
use std::fmt;
use std::io::Read;
use rand_core::{impls, Error, RngCore};
use rand_core::{impls, RngCore};
/// An RNG that reads random bytes straight from any type supporting
/// [`std::io::Read`], for example files.
@ -30,11 +30,10 @@ use rand_core::{impls, Error, RngCore};
///
/// `ReadRng` uses [`std::io::Read::read_exact`], which retries on interrupts.
/// All other errors from the underlying reader, including when it does not
/// have enough data, will only be reported through [`try_fill_bytes`].
/// have enough data, will only be reported through `try_fill_bytes`.
/// The other [`RngCore`] methods will panic in case of an error.
///
/// [`OsRng`]: rand::rngs::OsRng
/// [`try_fill_bytes`]: RngCore::try_fill_bytes
#[derive(Debug)]
pub struct ReadRng<R> {
reader: R,
@ -45,6 +44,14 @@ impl<R: Read> ReadRng<R> {
pub fn new(r: R) -> Self {
Self { reader: r }
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), ReadError> {
if dest.is_empty() {
return Ok(());
}
// Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`.
self.reader.read_exact(dest).map_err(ReadError)
}
}
impl<R: Read> RngCore for ReadRng<R> {
@ -61,16 +68,6 @@ impl<R: Read> RngCore for ReadRng<R> {
panic!("reading random bytes from Read implementation failed; error: {err}");
});
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
if dest.is_empty() {
return Ok(());
}
// Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`.
self.reader
.read_exact(dest)
.map_err(|e| Error::new(ReadError(e)))
}
}
/// `ReadRng` error type

View file

@ -7,7 +7,7 @@
use clap::{crate_version, Arg, ArgAction, Command};
use memchr::memchr_iter;
use rand::prelude::SliceRandom;
use rand::prelude::{IndexedRandom, SliceRandom};
use rand::{Rng, RngCore};
use std::collections::HashSet;
use std::fs::File;
@ -299,7 +299,7 @@ impl Shufable for RangeInclusive<usize> {
self.is_empty()
}
fn choose(&self, rng: &mut WrappedRng) -> usize {
rng.gen_range(self.clone())
rng.random_range(self.clone())
}
type PartialShuffleIterator<'b>
= NonrepeatingIterator<'b>
@ -348,7 +348,7 @@ impl<'a> NonrepeatingIterator<'a> {
match &mut self.buf {
NumberSet::AlreadyListed(already_listed) => {
let chosen = loop {
let guess = self.rng.gen_range(self.range.clone());
let guess = self.rng.random_range(self.range.clone());
let newly_inserted = already_listed.insert(guess);
if newly_inserted {
break guess;
@ -435,7 +435,7 @@ fn shuf_exec(input: &mut impl Shufable, opts: Options) -> UResult<()> {
.map_err_context(|| format!("failed to open random source {}", r.quote()))?;
WrappedRng::RngFile(rand_read_adapter::ReadRng::new(file))
}
None => WrappedRng::RngDefault(rand::thread_rng()),
None => WrappedRng::RngDefault(rand::rng()),
};
if opts.repeat {
@ -520,13 +520,6 @@ impl RngCore for WrappedRng {
Self::RngDefault(r) => r.fill_bytes(dest),
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
match self {
Self::RngFile(r) => r.try_fill_bytes(dest),
Self::RngDefault(r) => r.try_fill_bytes(dest),
}
}
}
#[cfg(test)]