@@ -16,11 +16,14 @@ use rand_core::{RngCore, Error, ErrorKind, impls};
16
16
17
17
18
18
/// An RNG that reads random bytes straight from a `Read`. This will
19
- /// work best with an infinite reader, but this is not required.
19
+ /// work best with an infinite reader, but that is not required.
20
20
///
21
21
/// # Panics
22
22
///
23
- /// It will panic if it there is insufficient data to fulfill a request.
23
+ /// `ReadRng` uses `std::io::read_exact`, which retries on interrupts. All other
24
+ /// errors from the underlying reader, including when it does not have enough
25
+ /// data, will only be reported through `try_fill_bytes`. The other `RngCore`
26
+ /// methods will panic in case of an error error.
24
27
///
25
28
/// # Example
26
29
///
@@ -53,21 +56,22 @@ impl<R: Read> RngCore for ReadRng<R> {
53
56
fn next_u64 ( & mut self ) -> u64 {
54
57
impls:: next_u64_via_fill ( self )
55
58
}
56
-
59
+
57
60
fn fill_bytes ( & mut self , dest : & mut [ u8 ] ) {
58
- self . try_fill_bytes ( dest) . unwrap ( ) ;
61
+ self . try_fill_bytes ( dest) . unwrap_or_else ( |err|
62
+ panic ! ( "reading random bytes from Read implementation failed; error: {}" , err) ) ;
59
63
}
60
64
61
65
fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
62
66
if dest. len ( ) == 0 { return Ok ( ( ) ) ; }
63
67
// Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`.
64
68
self . reader . read_exact ( dest) . map_err ( |err| {
65
69
match err. kind ( ) {
66
- :: std:: io:: ErrorKind :: WouldBlock => Error :: with_cause (
67
- ErrorKind :: NotReady ,
68
- "reading from random device would block " , err) ,
70
+ :: std:: io:: ErrorKind :: UnexpectedEof => Error :: with_cause (
71
+ ErrorKind :: Unavailable ,
72
+ "not enough bytes available, reached end of source " , err) ,
69
73
_ => Error :: with_cause ( ErrorKind :: Unavailable ,
70
- "error reading random device " , err)
74
+ "error reading from Read source " , err)
71
75
}
72
76
} )
73
77
}
@@ -90,6 +94,7 @@ mod test {
90
94
assert_eq ! ( rng. next_u64( ) , 2_u64 . to_be( ) ) ;
91
95
assert_eq ! ( rng. next_u64( ) , 3_u64 . to_be( ) ) ;
92
96
}
97
+
93
98
#[ test]
94
99
fn test_reader_rng_u32 ( ) {
95
100
let v = vec ! [ 0u8 , 0 , 0 , 1 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 3 ] ;
@@ -99,6 +104,7 @@ mod test {
99
104
assert_eq ! ( rng. next_u32( ) , 2_u32 . to_be( ) ) ;
100
105
assert_eq ! ( rng. next_u32( ) , 3_u32 . to_be( ) ) ;
101
106
}
107
+
102
108
#[ test]
103
109
fn test_reader_rng_fill_bytes ( ) {
104
110
let v = [ 1u8 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
0 commit comments