summaryrefslogtreecommitdiff
path: root/rand/src/rngs/adapter/read.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rand/src/rngs/adapter/read.rs')
-rw-r--r--rand/src/rngs/adapter/read.rs53
1 files changed, 32 insertions, 21 deletions
diff --git a/rand/src/rngs/adapter/read.rs b/rand/src/rngs/adapter/read.rs
index 30b6de6..901462e 100644
--- a/rand/src/rngs/adapter/read.rs
+++ b/rand/src/rngs/adapter/read.rs
@@ -10,12 +10,13 @@
//! A wrapper around any Read to treat it as an RNG.
use std::io::Read;
+use std::fmt;
-use rand_core::{RngCore, Error, ErrorKind, impls};
+use rand_core::{RngCore, Error, impls};
/// An RNG that reads random bytes straight from any type supporting
-/// `std::io::Read`, for example files.
+/// [`std::io::Read`], for example files.
///
/// This will work best with an infinite reader, but that is not required.
///
@@ -24,10 +25,10 @@ use rand_core::{RngCore, Error, ErrorKind, impls};
///
/// # Panics
///
-/// `ReadRng` uses `std::io::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`]. The other
-/// [`RngCore`] methods will panic in case of an error.
+/// `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`].
+/// The other [`RngCore`] methods will panic in case of an error.
///
/// # Example
///
@@ -40,9 +41,8 @@ use rand_core::{RngCore, Error, ErrorKind, impls};
/// println!("{:x}", rng.gen::<u32>());
/// ```
///
-/// [`OsRng`]: ../struct.OsRng.html
-/// [`RngCore`]: ../../trait.RngCore.html
-/// [`try_fill_bytes`]: ../../trait.RngCore.html#method.tymethod.try_fill_bytes
+/// [`OsRng`]: crate::rngs::OsRng
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
#[derive(Debug)]
pub struct ReadRng<R> {
reader: R
@@ -72,24 +72,33 @@ impl<R: Read> RngCore for ReadRng<R> {
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- if dest.len() == 0 { return Ok(()); }
+ if dest.is_empty() { return Ok(()); }
// Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`.
- self.reader.read_exact(dest).map_err(|err| {
- match err.kind() {
- ::std::io::ErrorKind::UnexpectedEof => Error::with_cause(
- ErrorKind::Unavailable,
- "not enough bytes available, reached end of source", err),
- _ => Error::with_cause(ErrorKind::Unavailable,
- "error reading from Read source", err)
- }
- })
+ self.reader.read_exact(dest).map_err(|e| Error::new(ReadError(e)))
}
}
+/// `ReadRng` error type
+#[derive(Debug)]
+pub struct ReadError(std::io::Error);
+
+impl fmt::Display for ReadError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "ReadError: {}", self.0)
+ }
+}
+
+impl std::error::Error for ReadError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ Some(&self.0)
+ }
+}
+
+
#[cfg(test)]
mod test {
use super::ReadRng;
- use {RngCore, ErrorKind};
+ use crate::RngCore;
#[test]
fn test_reader_rng_u64() {
@@ -132,6 +141,8 @@ mod test {
let mut rng = ReadRng::new(&v[..]);
- assert!(rng.try_fill_bytes(&mut w).err().unwrap().kind == ErrorKind::Unavailable);
+ let result = rng.try_fill_bytes(&mut w);
+ assert!(result.is_err());
+ println!("Error: {}", result.unwrap_err());
}
}