diff --git a/src/lib.rs b/src/lib.rs index ce07b88eef..ece97fac80 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -276,7 +276,7 @@ use prng::Isaac64Rng as IsaacWordRng; use distributions::{Range, IndependentSample}; use distributions::range::SampleRange; -#[cfg(feature="std")]use reseeding::{ReseedingRng, ReseedWithNew}; +#[cfg(feature="std")]use reseeding::{ReseedingRng}; // public modules pub mod distributions; @@ -942,20 +942,20 @@ pub fn weak_rng() -> XorShiftRng { #[cfg(feature="std")] #[derive(Clone, Debug)] pub struct ThreadRng { - rng: Rc>>, + rng: Rc>>, } #[cfg(feature="std")] thread_local!( - static THREAD_RNG_KEY: Rc>> = { + static THREAD_RNG_KEY: Rc>> = { const THREAD_RNG_RESEED_THRESHOLD: u64 = 32_768; - let r = match StdRng::new() { - Ok(r) => r, - Err(e) => panic!("could not initialize thread_rng: {:?}", e) - }; + let mut entropy_source = EntropySource::new() + .expect("could not initialize thread_rng"); + let r = StdRng::from_rng(&mut entropy_source) + .expect("could not initialize thread_rng"); let rng = ReseedingRng::new(r, THREAD_RNG_RESEED_THRESHOLD, - ReseedWithNew); + entropy_source); Rc::new(RefCell::new(rng)) } ); diff --git a/src/reseeding.rs b/src/reseeding.rs index 1fdb5dc20b..9af642c42a 100644 --- a/src/reseeding.rs +++ b/src/reseeding.rs @@ -11,9 +11,7 @@ //! A wrapper around another RNG that reseeds it after it //! generates a certain number of random bytes. -use {Rng, Error}; -#[cfg(feature="std")] -use NewSeeded; +use {Rng, SeedableRng, Error}; /// A wrapper around any RNG which reseeds the underlying RNG after it /// has generated a certain number of random bytes. @@ -23,10 +21,10 @@ pub struct ReseedingRng { generation_threshold: u64, bytes_generated: u64, /// Controls the behaviour when reseeding the RNG. - pub reseeder: Rsdr, + reseeder: Rsdr, } -impl> ReseedingRng { +impl ReseedingRng { /// Create a new `ReseedingRng` with the given parameters. /// /// # Arguments @@ -47,14 +45,14 @@ impl> ReseedingRng { /// generated exceed the threshold. pub fn reseed_if_necessary(&mut self) { if self.bytes_generated >= self.generation_threshold { - self.reseeder.reseed(&mut self.rng).unwrap(); + R::from_rng(&mut self.reseeder).map(|result| self.rng = result).unwrap(); self.bytes_generated = 0; } } } -impl> Rng for ReseedingRng { +impl Rng for ReseedingRng { fn next_u32(&mut self) -> u32 { self.reseed_if_necessary(); self.bytes_generated += 4; @@ -80,35 +78,11 @@ impl> Rng for ReseedingRng { } } -/// Something that can be used to reseed an RNG via `ReseedingRng`. -/// -/// Note that implementations should support `Clone` only if reseeding is -/// deterministic (no external entropy source). This is so that a `ReseedingRng` -/// only supports `Clone` if fully deterministic. -pub trait Reseeder { - /// Reseed the given RNG. - /// - /// On error, this should just forward the source error; errors are handled - /// by the caller. - fn reseed(&mut self, rng: &mut R) -> Result<(), Error>; -} - -/// Reseed an RNG using `NewSeeded` to replace the current instance. -#[cfg(feature="std")] -#[derive(Debug)] -pub struct ReseedWithNew; - -#[cfg(feature="std")] -impl Reseeder for ReseedWithNew { - fn reseed(&mut self, rng: &mut R) -> Result<(), Error> { - R::new().map(|result| *rng = result) - } -} #[cfg(test)] mod test { use {impls, le}; - use super::{ReseedingRng, Reseeder}; + use super::{ReseedingRng}; use {SeedableRng, Rng, Error}; struct Counter { @@ -139,17 +113,20 @@ mod test { } #[derive(Debug, Clone)] - struct ReseedCounter; - impl Reseeder for ReseedCounter { - fn reseed(&mut self, rng: &mut Counter) -> Result<(), Error> { - *rng = Counter { i: 0 }; + struct ResetCounter; + impl Rng for ResetCounter { + fn next_u32(&mut self) -> u32 { unimplemented!() } + fn next_u64(&mut self) -> u64 { unimplemented!() } + fn fill_bytes(&mut self, _dest: &mut [u8]) { unimplemented!() } + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + for i in dest.iter_mut() { *i = 0; } Ok(()) } } #[test] fn test_reseeding() { - let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedCounter); + let mut rs = ReseedingRng::new(Counter {i:0}, 400, ResetCounter); let mut i = 0; for _ in 0..1000 {