@@ -129,6 +129,41 @@ pub use rng::{Fill, Rng};
129129#[ cfg( feature = "thread_rng" ) ]
130130use 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