diff --git a/.travis.yml b/.travis.yml index 988b2393072..92ff8ff4983 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,8 @@ matrix: - cargo test --features serde-1,log,nightly - cargo test --benches - cargo doc --no-deps --all --all-features + - cargo --list | egrep "^\s*deadlinks$" -q || cargo install cargo-deadlinks + - cargo deadlinks --dir target/doc after_success: - travis-cargo --only nightly doc-upload diff --git a/Cargo.toml b/Cargo.toml index 069037a9b0c..479c2adb2fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rand" -version = "0.5.0-pre.0" +version = "0.5.0-pre.0" # NB: When modifying, also modify html_root_url in lib.rs authors = ["The Rust Project Developers"] license = "MIT/Apache-2.0" readme = "README.md" @@ -29,7 +29,7 @@ serde-1 = ["serde", "serde_derive"] # enables serialisation for PRNGs members = ["rand_core"] [dependencies] -rand_core = { version = '0.1.0-pre.0', default-features = false } +rand_core = { path="rand_core", default-features = false } log = { version = "0.4", optional = true } serde = { version = "1", optional = true } serde_derive = { version = "1", optional = true } @@ -54,3 +54,7 @@ stdweb = { version = "0.4", optional = true } # This is for testing serde, unfortunately we can't specify feature-gated dev # deps yet, see: https://github.com/rust-lang/cargo/issues/1596 bincode = "1.0" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ "--all" ] # also document rand_core diff --git a/benches/generators.rs b/benches/generators.rs index 16bd6d56af9..e432f563a8c 100644 --- a/benches/generators.rs +++ b/benches/generators.rs @@ -10,10 +10,10 @@ use std::mem::size_of; use test::{black_box, Bencher}; use rand::{RngCore, Rng, SeedableRng, NewRng}; -use rand::{StdRng, SmallRng, OsRng, JitterRng, EntropyRng}; -use rand::{XorShiftRng, Hc128Rng, IsaacRng, Isaac64Rng, ChaChaRng}; -use rand::reseeding::ReseedingRng; +use rand::{StdRng, SmallRng, OsRng, EntropyRng, ReseedingRng}; +use rand::prng::{XorShiftRng, Hc128Rng, IsaacRng, Isaac64Rng, ChaChaRng}; use rand::prng::hc128::Hc128Core; +use rand::jitter::JitterRng; use rand::thread_rng; macro_rules! gen_bytes { diff --git a/rand_core/Cargo.toml b/rand_core/Cargo.toml index 92109593eb2..59742bc1b2f 100644 --- a/rand_core/Cargo.toml +++ b/rand_core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rand_core" -version = "0.1.0-pre.0" +version = "0.1.0-pre.0" # NB: When modifying, also modify html_root_url in lib.rs authors = ["The Rust Project Developers"] license = "MIT/Apache-2.0" readme = "README.md" diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs index fd72f80c346..5eb1e174b20 100644 --- a/rand_core/src/lib.rs +++ b/rand_core/src/lib.rs @@ -83,8 +83,8 @@ pub mod le; /// output (except by communicating that the release has breaking changes). /// /// Typically implementators will implement only one of the methods available -/// in this trait directly, then use the helper functions from the [`impls`] -/// module to implement the other methods. +/// in this trait directly, then use the helper functions from the +/// [`rand_core::impls`] module to implement the other methods. /// /// It is recommended that implementations also implement: /// @@ -131,7 +131,7 @@ pub mod le; /// [rand]: https://crates.io/crates/rand /// [`Rng`]: ../rand/trait.Rng.html /// [`SeedableRng`]: trait.SeedableRng.html -/// [`impls`]: impls/index.html +/// [`rand_core::impls`]: ../rand_core/impls/index.html /// [`try_fill_bytes`]: trait.RngCore.html#tymethod.try_fill_bytes /// [`fill_bytes`]: trait.RngCore.html#tymethod.fill_bytes /// [`next_u32`]: trait.RngCore.html#tymethod.next_u32 @@ -143,23 +143,23 @@ pub trait RngCore { /// RNGs must implement at least one method from this trait directly. In /// the case this method is not implemented directly, it can be implemented /// using `self.next_u64() as u32` or - /// [via `fill_bytes`](impls/fn.next_u32_via_fill.html). + /// [via `fill_bytes`](../rand_core/impls/fn.next_u32_via_fill.html). fn next_u32(&mut self) -> u32; /// Return the next random `u64`. /// /// RNGs must implement at least one method from this trait directly. In /// the case this method is not implemented directly, it can be implemented - /// [via `next_u32`](impls/fn.next_u64_via_u32.html) or - /// [via `fill_bytes`](impls/fn.next_u64_via_fill.html). + /// [via `next_u32`](../rand_core/impls/fn.next_u64_via_u32.html) or + /// [via `fill_bytes`](../rand_core/impls/fn.next_u64_via_fill.html). fn next_u64(&mut self) -> u64; /// Fill `dest` with random data. /// /// RNGs must implement at least one method from this trait directly. In /// the case this method is not implemented directly, it can be implemented - /// [via `next_u32`](impls/fn.fill_bytes_via_u32.html) or - /// [via `next_u64`](impls/fn.fill_bytes_via_u64.html) or + /// [via `next_u32`](../rand_core/impls/fn.fill_bytes_via_u32.html) or + /// [via `next_u64`](../rand_core/impls/fn.fill_bytes_via_u64.html) or /// via `try_fill_bytes`; if this generator can fail the implementation /// must choose how best to handle errors here (e.g. panic with a /// descriptive message or log a warning and retry a few times). @@ -329,7 +329,7 @@ pub trait SeedableRng: Sized { /// /// Seeding a small PRNG from another small PRNG is possible, but /// something to be careful with. An extreme example of how this can go - /// wrong is seeding an [`XorShiftRng`] from another [`XorShiftRng`], which + /// wrong is seeding an Xorshift RNG from another Xorshift RNG, which /// will effectively clone the generator. In general seeding from a /// generator which is hard to predict is probably okay. /// @@ -338,7 +338,6 @@ pub trait SeedableRng: Sized { /// /// [`NewRng`]: ../rand/trait.NewRng.html /// [`OsRng`]: ../rand/os/struct.OsRng.html - /// [`XorShiftRng`]: ../rand/struct.XorShiftRng.html fn from_rng(mut rng: R) -> Result { let mut seed = Self::Seed::default(); rng.try_fill_bytes(seed.as_mut())?; diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs index dbe0b0ef786..768bbc3c359 100644 --- a/src/distributions/mod.rs +++ b/src/distributions/mod.rs @@ -246,7 +246,7 @@ impl<'a, T, D: Distribution> Distribution for &'a D { /// use rand::distributions::Uniform; /// /// let mut rng = thread_rng(); -/// let mut erased_rng: &mut RngCore = &mut rng; +/// let erased_rng: &mut RngCore = &mut rng; /// let val: f32 = erased_rng.sample(Uniform); /// println!("f32 from (0,1): {}", val); /// ``` diff --git a/src/distributions/range.rs b/src/distributions/range.rs index 13db0b534df..7f32f482020 100644 --- a/src/distributions/range.rs +++ b/src/distributions/range.rs @@ -53,7 +53,7 @@ use distributions::float::IntoFloat; /// ``` #[derive(Clone, Copy, Debug)] pub struct Range { - inner: X::T, + inner: X::Impl, } impl Range { @@ -61,21 +61,21 @@ impl Range { /// open range `[low, high)` (excluding `high`). Panics if `low >= high`. pub fn new(low: X, high: X) -> Range { assert!(low < high, "Range::new called with `low >= high`"); - Range { inner: X::T::new(low, high) } + Range { inner: X::Impl::new(low, high) } } /// Create a new `Range` instance which samples uniformly from the closed /// range `[low, high]` (inclusive). Panics if `low >= high`. pub fn new_inclusive(low: X, high: X) -> Range { assert!(low < high, "Range::new called with `low >= high`"); - Range { inner: X::T::new_inclusive(low, high) } + Range { inner: X::Impl::new_inclusive(low, high) } } /// Sample a single value uniformly from `[low, high)`. /// Panics if `low >= high`. pub fn sample_single(low: X, high: X, rng: &mut R) -> X { assert!(low < high, "Range::sample_single called with low >= high"); - X::T::sample_single(low, high, rng) + X::Impl::sample_single(low, high, rng) } } @@ -88,7 +88,8 @@ impl Distribution for Range { /// Helper trait for creating objects using the correct implementation of /// `RangeImpl` for the sampling type; this enables `Range::new(a, b)` to work. pub trait SampleRange: PartialOrd+Sized { - type T: RangeImpl; + /// The `RangeImpl` implementation supporting type `X`. + type Impl: RangeImpl; } /// Helper trait handling actual range sampling. @@ -124,7 +125,7 @@ pub trait SampleRange: PartialOrd+Sized { /// } /// /// impl SampleRange for MyF32 { -/// type T = RangeMyF32; +/// type Impl = RangeMyF32; /// } /// /// let (low, high) = (MyF32(17.0f32), MyF32(22.0f32)); @@ -183,7 +184,7 @@ macro_rules! range_int_impl { ($ty:ty, $signed:ty, $unsigned:ident, $i_large:ident, $u_large:ident) => { impl SampleRange for $ty { - type T = RangeInt<$ty>; + type Impl = RangeInt<$ty>; } impl RangeImpl for RangeInt<$ty> { @@ -428,7 +429,7 @@ pub struct RangeFloat { macro_rules! range_float_impl { ($ty:ty, $bits_to_discard:expr, $next_u:ident) => { impl SampleRange for $ty { - type T = RangeFloat<$ty>; + type Impl = RangeFloat<$ty>; } impl RangeImpl for RangeFloat<$ty> { @@ -566,7 +567,7 @@ mod tests { } } impl SampleRange for MyF32 { - type T = RangeMyF32; + type Impl = RangeMyF32; } let (low, high) = (MyF32{ x: 17.0f32 }, MyF32{ x: 22.0f32 }); diff --git a/src/entropy_rng.rs b/src/entropy_rng.rs index b97d9ed7f81..bcf1c6608b0 100644 --- a/src/entropy_rng.rs +++ b/src/entropy_rng.rs @@ -11,7 +11,8 @@ //! Entropy generator, or wrapper around external generators use rand_core::{RngCore, CryptoRng, Error, impls}; -use {OsRng, JitterRng}; +use os::OsRng; +use jitter::JitterRng; /// A generator provided specifically for securely seeding algorithmic /// generators (PRNGs). diff --git a/src/jitter.rs b/src/jitter.rs index 56c4f1fe596..719afa3ae7a 100644 --- a/src/jitter.rs +++ b/src/jitter.rs @@ -16,6 +16,11 @@ //! Non-physical true random number generator based on timing jitter. +// Note: the C implementation of `Jitterentropy` relies on being compiled +// without optimizations. This implementation goes through lengths to make the +// compiler not optimise out what is technically dead code, but that does +// influence timing jitter. + use rand_core::{RngCore, CryptoRng, Error, ErrorKind, impls}; use core::{fmt, mem, ptr}; @@ -31,7 +36,7 @@ const MEMORY_SIZE: usize = MEMORY_BLOCKS * MEMORY_BLOCKSIZE; /// /// This is a true random number generator, as opposed to pseudo-random /// generators. Random numbers generated by `JitterRng` can be seen as fresh -/// entropy. A consequence is that is orders of magnitude slower than `OsRng` +/// entropy. A consequence is that is orders of magnitude slower than [`OsRng`] /// and PRNGs (about 103..106 slower). /// /// There are very few situations where using this RNG is appropriate. Only very @@ -40,21 +45,19 @@ const MEMORY_SIZE: usize = MEMORY_BLOCKS * MEMORY_BLOCKSIZE; /// predict. /// /// Use of `JitterRng` is recommended for initializing cryptographic PRNGs when -/// `OsRng` is not available. +/// [`OsRng`] is not available. /// /// This implementation is based on /// [Jitterentropy](http://www.chronox.de/jent.html) version 2.1.0. -// -// Note: the C implementation relies on being compiled without optimizations. -// This implementation goes through lengths to make the compiler not optimise -// out what is technically dead code, but that does influence timing jitter. +/// +/// [`OsRng`]: ../os/struct.OsRng.html pub struct JitterRng { data: u64, // Actual random number // Number of rounds to run the entropy collector per 64 bits rounds: u8, // Timer used by `measure_jitter` timer: fn() -> u64, - // Memory for the Memory Access noise source FIXME + // Memory for the Memory Access noise source mem_prev_index: u16, // Make `next_u32` not waste 32 bits data_half_used: bool, @@ -100,7 +103,9 @@ impl fmt::Debug for JitterRng { } } -/// An error that can occur when `test_timer` fails. +/// An error that can occur when [`JitterRng::test_timer`] fails. +/// +/// [`JitterRng::test_timer`]: struct.JitterRng.html#method.test_timer #[derive(Debug, Clone, PartialEq, Eq)] pub enum TimerError { /// No timer available. @@ -157,8 +162,9 @@ impl From for Error { static JITTER_ROUNDS: AtomicUsize = ATOMIC_USIZE_INIT; impl JitterRng { - /// Create a new `JitterRng`. - /// Makes use of `std::time` for a timer. + /// Create a new `JitterRng`. Makes use of `std::time` for a timer, or a + /// platform-specific function with higher accuracy if necessary and + /// available. /// /// During initialization CPU execution timing jitter is measured a few /// hundred times. If this does not pass basic quality tests, an error is @@ -188,10 +194,44 @@ impl JitterRng { /// The timer must have nanosecond precision. /// /// This method is more low-level than `new()`. It is the responsibility of - /// the caller to run `test_timer` before using any numbers generated with - /// `JitterRng`, and optionally call `set_rounds()`. Also it is important to - /// call `gen_entropy` once before using the first result to initialize the - /// entropy collection pool. + /// the caller to run [`test_timer`] before using any numbers generated with + /// `JitterRng`, and optionally call [`set_rounds`]. Also it is important to + /// consume at least one `u64` before using the first result to initialize + /// the entropy collection pool. + /// + /// # Example + /// + /// ```rust + /// # use rand::{Rng, Error}; + /// use rand::jitter::JitterRng; + /// + /// # fn try_inner() -> Result<(), Error> { + /// fn get_nstime() -> u64 { + /// use std::time::{SystemTime, UNIX_EPOCH}; + /// + /// let dur = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + /// // The correct way to calculate the current time is + /// // `dur.as_secs() * 1_000_000_000 + dur.subsec_nanos() as u64` + /// // But this is faster, and the difference in terms of entropy is + /// // negligible (log2(10^9) == 29.9). + /// dur.as_secs() << 30 | dur.subsec_nanos() as u64 + /// } + /// + /// let mut rng = JitterRng::new_with_timer(get_nstime); + /// let rounds = rng.test_timer()?; + /// rng.set_rounds(rounds); // optional + /// let _ = rng.gen::(); + /// + /// // Ready for use + /// let v: u64 = rng.gen(); + /// # Ok(()) + /// # } + /// + /// # let _ = try_inner(); + /// ``` + /// + /// [`test_timer`]: struct.JitterRng.html#method.test_timer + /// [`set_rounds`]: struct.JitterRng.html#method.set_rounds pub fn new_with_timer(timer: fn() -> u64) -> JitterRng { JitterRng { data: 0, @@ -206,10 +246,12 @@ impl JitterRng { /// This must be greater than zero, and has a big impact on performance /// and output quality. /// - /// `new_with_timer` conservatively uses 64 rounds, but often less rounds + /// [`new_with_timer`] conservatively uses 64 rounds, but often less rounds /// can be used. The `test_timer()` function returns the minimum number of /// rounds required for full strength (platform dependent), so one may use /// `rng.set_rounds(rng.test_timer()?);` or cache the value. + /// + /// [`new_with_timer`]: struct.JitterRng.html#method.new_with_timer pub fn set_rounds(&mut self, rounds: u8) { assert!(rounds > 0); self.rounds = rounds; @@ -447,17 +489,14 @@ impl JitterRng { self.data } - #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] - pub fn test_timer(&mut self) -> Result { - return Err(TimerError::NoTimer); - } - /// Basic quality tests on the timer, by measuring CPU timing jitter a few /// hundred times. /// /// If succesful, this will return the estimated number of rounds necessary - /// to collect 64 bits of entropy. Otherwise a `TimerError` with the cause + /// to collect 64 bits of entropy. Otherwise a [`TimerError`] with the cause /// of the failure will be returned. + /// + /// [`TimerError`]: enum.TimerError.html #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] pub fn test_timer(&mut self) -> Result { debug!("JitterRng: testing timer ..."); @@ -595,6 +634,10 @@ impl JitterRng { Ok(log2_lookup[delta_average as usize]) } } + #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] + pub fn test_timer(&mut self) -> Result { + return Err(TimerError::NoTimer); + } /// Statistical test: return the timer delta of one normal run of the /// `JitterEntropy` entropy collector. @@ -639,34 +682,18 @@ impl JitterRng { /// for the available entropy. /// /// ```rust,no_run - /// use rand::JitterRng; - /// + /// use rand::jitter::JitterRng; + /// # /// # use std::error::Error; /// # use std::fs::File; /// # use std::io::Write; /// # /// # fn try_main() -> Result<(), Box> { - /// fn get_nstime() -> u64 { - /// use std::time::{SystemTime, UNIX_EPOCH}; - /// - /// let dur = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); - /// // The correct way to calculate the current time is - /// // `dur.as_secs() * 1_000_000_000 + dur.subsec_nanos() as u64` - /// // But this is faster, and the difference in terms of entropy is - /// // negligible (log2(10^9) == 29.9). - /// dur.as_secs() << 30 | dur.subsec_nanos() as u64 - /// } - /// - /// // Do not initialize with `JitterRng::new`, but with `new_with_timer`. - /// // 'new' always runst `test_timer`, and can therefore fail to - /// // initialize. We want to be able to get the statistics even when the - /// // timer test fails. - /// let mut rng = JitterRng::new_with_timer(get_nstime); + /// let mut rng = JitterRng::new()?; /// /// // 1_000_000 results are required for the NIST SP 800-90B Entropy /// // Estimation Suite - /// // FIXME: this number is smaller here, otherwise the Doc-test is too slow - /// const ROUNDS: usize = 10_000; + /// const ROUNDS: usize = 1_000_000; /// let mut deltas_variable: Vec = Vec::with_capacity(ROUNDS); /// let mut deltas_minimal: Vec = Vec::with_capacity(ROUNDS); /// @@ -687,6 +714,7 @@ impl JitterRng { /// # try_main().unwrap(); /// # } /// ``` + /// #[cfg(feature="std")] pub fn timer_stats(&mut self, var_rounds: bool) -> i64 { let mut mem = [0; MEMORY_SIZE]; @@ -701,15 +729,16 @@ impl JitterRng { #[cfg(feature="std")] mod platform { - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows", all(target_arch = "wasm32", not(target_os = "emscripten")))))] + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows", + all(target_arch = "wasm32", not(target_os = "emscripten")))))] pub fn get_nstime() -> u64 { use std::time::{SystemTime, UNIX_EPOCH}; let dur = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); // The correct way to calculate the current time is // `dur.as_secs() * 1_000_000_000 + dur.subsec_nanos() as u64` - // But this is faster, and the difference in terms of entropy is negligible - // (log2(10^9) == 29.9). + // But this is faster, and the difference in terms of entropy is + // negligible (log2(10^9) == 29.9). dur.as_secs() << 30 | dur.subsec_nanos() as u64 } @@ -717,11 +746,11 @@ mod platform { pub fn get_nstime() -> u64 { extern crate libc; // On Mac OS and iOS std::time::SystemTime only has 1000ns resolution. - // We use `mach_absolute_time` instead. This provides a CPU dependent unit, - // to get real nanoseconds the result should by multiplied by numer/denom - // from `mach_timebase_info`. - // But we are not interested in the exact nanoseconds, just entropy. So we - // use the raw result. + // We use `mach_absolute_time` instead. This provides a CPU dependent + // unit, to get real nanoseconds the result should by multiplied by + // numer/denom from `mach_timebase_info`. + // But we are not interested in the exact nanoseconds, just entropy. So + // we use the raw result. unsafe { libc::mach_absolute_time() } } @@ -787,7 +816,7 @@ impl CryptoRng for JitterRng {} #[cfg(test)] mod test_jitter_init { - use JitterRng; + use jitter::JitterRng; #[cfg(feature="std")] #[test] diff --git a/src/lib.rs b/src/lib.rs index 6f228ba224b..c3f7997dea7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,13 +53,21 @@ //! to seed from a strong parent generator with [`from_rng`]: //! //! ``` +//! # use rand::{Rng, Error}; //! // seed with fresh entropy: //! use rand::{StdRng, NewRng}; //! let mut rng = StdRng::new(); +//! # let v: u32 = rng.gen(); //! //! // seed from thread_rng: //! use rand::{SmallRng, SeedableRng, thread_rng}; -//! let mut rng = SmallRng::from_rng(thread_rng()); +//! +//! # fn try_inner() -> Result<(), Error> { +//! let mut rng = SmallRng::from_rng(thread_rng())?; +//! # let v: u32 = rng.gen(); +//! # Ok(()) +//! # } +//! # try_inner().unwrap() //! ``` //! //! In case you specifically want to have a reproducible stream of "random" @@ -161,11 +169,11 @@ //! [`SmallRng`]: struct.SmallRng.html //! [`ReseedingRng`]: reseeding/struct.ReseedingRng.html //! [`prng`]: prng/index.html -//! [`IsaacRng::new_from_u64`]: struct.IsaacRng.html#method.new_from_u64 +//! [`IsaacRng::new_from_u64`]: prng/isaac/struct.IsaacRng.html#method.new_from_u64 //! [`Hc128Rng`]: prng/hc128/struct.Hc128Rng.html //! [`ChaChaRng`]: prng/chacha/struct.ChaChaRng.html -//! [`IsaacRng`]: prng/struct.IsaacRng.html -//! [`Isaac64Rng`]: prng/struct.Isaac64Rng.html +//! [`IsaacRng`]: prng/isaac/struct.IsaacRng.html +//! [`Isaac64Rng`]: prng/isaac64/struct.Isaac64Rng.html //! [`seq`]: seq/index.html //! [`distributions`]: distributions/index.html //! [`Uniform`]: distributions/struct.Uniform.html @@ -174,7 +182,9 @@ html_favicon_url = "https://www.rust-lang.org/favicon.ico", html_root_url = "https://docs.rs/rand/0.5")] +#![deny(missing_docs)] #![deny(missing_debug_implementations)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![cfg_attr(not(feature="std"), no_std)] #![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))] @@ -203,45 +213,36 @@ extern crate rand_core; #[cfg(all(feature="std", not(feature = "log")))] macro_rules! error { ($($x:tt)*) => () } -use core::{marker, mem, slice}; - -// re-exports from rand_core +// Re-exports from rand_core pub use rand_core::{RngCore, BlockRngCore, CryptoRng, SeedableRng}; pub use rand_core::{ErrorKind, Error}; -// external rngs -pub use jitter::JitterRng; -#[cfg(feature="std")] pub use os::OsRng; - -// pseudo rngs -pub mod prng; -pub use isaac::{IsaacRng, Isaac64Rng}; -pub use chacha::ChaChaRng; -pub use prng::XorShiftRng; -pub use prng::Hc128Rng; - -// convenience and derived rngs +// Public exports #[cfg(feature="std")] pub use entropy_rng::EntropyRng; +#[cfg(feature="std")] pub use os::OsRng; +pub use reseeding::ReseedingRng; #[cfg(feature="std")] pub use thread_rng::{ThreadRng, thread_rng}; #[cfg(feature="std")] #[allow(deprecated)] pub use thread_rng::random; -use distributions::{Distribution, Uniform, Range}; -use distributions::range::SampleRange; - -// public modules +// Public modules pub mod distributions; -pub mod jitter; -pub mod mock; -#[cfg(feature="std")] pub mod os; +pub mod jitter; // Public because of the error type. +pub mod mock; // Public so we don't export `StepRng` directly, making it a bit + // more clear it is intended for testing. +pub mod prng; #[cfg(feature="std")] pub mod read; -pub mod reseeding; #[cfg(feature = "alloc")] pub mod seq; -// These tiny modules are here to avoid API breakage, probably only temporarily +// These modules are public to avoid API breakage, probably only temporarily. +// Hidden in the documentation. +#[cfg(feature="std")] #[doc(hidden)] pub mod os; +#[doc(hidden)] pub use prng::{ChaChaRng, IsaacRng, Isaac64Rng, XorShiftRng}; +#[doc(hidden)] pub mod chacha { //! The ChaCha random number generator. pub use prng::ChaChaRng; } +#[doc(hidden)] pub mod isaac { //! The ISAAC random number generator. pub use prng::{IsaacRng, Isaac64Rng}; @@ -249,14 +250,23 @@ pub mod isaac { // private modules #[cfg(feature="std")] mod entropy_rng; +mod reseeding; #[cfg(feature="std")] mod thread_rng; -/// A type that can be randomly generated using an `Rng`. +// Normal imports just for this file +use core::{marker, mem, slice}; +use distributions::{Distribution, Uniform, Range}; +use distributions::range::SampleRange; +use prng::hc128::Hc128Rng; + + +/// A type that can be randomly generated using an [`Rng`]. /// /// This is merely an adaptor around the [`Uniform`] distribution for /// convenience and backwards-compatibility. /// +/// [`Rng`]: trait.Rng.html /// [`Uniform`]: distributions/struct.Uniform.html #[deprecated(since="0.5.0", note="replaced by distributions::Uniform")] pub trait Rand : Sized { @@ -293,88 +303,73 @@ pub trait Rand : Sized { /// Example: /// /// ```rust +/// # use rand::thread_rng; /// use rand::Rng; /// /// fn foo(rng: &mut R) -> f32 { /// rng.gen() /// } +/// +/// # let v = foo(&mut thread_rng()); /// ``` /// -/// [`RngCore`]: https://docs.rs/rand_core/0.1/rand_core/trait.RngCore.html +/// [`RngCore`]: trait.RngCore.html pub trait Rng: RngCore { - /// Fill `dest` entirely with random bytes (uniform value distribution), - /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices - /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.). - /// - /// On big-endian platforms this performs byte-swapping to ensure - /// portability of results from reproducible generators. - /// - /// This uses [`fill_bytes`] internally which may handle some RNG errors - /// implicitly (e.g. waiting if the OS generator is not ready), but panics - /// on other errors. See also [`try_fill`] which returns errors. - /// + /// Return a random value supporting the [`Uniform`] distribution. + /// + /// [`Uniform`]: distributions/struct.Uniform.html + /// /// # Example - /// + /// /// ```rust /// use rand::{thread_rng, Rng}; - /// - /// let mut arr = [0i8; 20]; - /// thread_rng().try_fill(&mut arr[..]); + /// + /// let mut rng = thread_rng(); + /// let x: u32 = rng.gen(); + /// println!("{}", x); + /// println!("{:?}", rng.gen::<(f64, bool)>()); /// ``` - /// - /// [`fill_bytes`]: https://docs.rs/rand_core/0.1/rand_core/trait.RngCore.html#method.fill_bytes - /// [`try_fill`]: trait.Rng.html#method.try_fill - /// [`AsByteSliceMut`]: trait.AsByteSliceMut.html - fn fill(&mut self, dest: &mut T) { - self.fill_bytes(dest.as_byte_slice_mut()); - dest.to_le(); + #[inline(always)] + fn gen(&mut self) -> T where Uniform: Distribution { + Uniform.sample(self) } - - /// Fill `dest` entirely with random bytes (uniform value distribution), - /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices - /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.). - /// - /// On big-endian platforms this performs byte-swapping to ensure - /// portability of results from reproducible generators. - /// - /// This uses [`try_fill_bytes`] internally and forwards all RNG errors. In - /// some cases errors may be resolvable; see [`ErrorKind`] and - /// documentation for the RNG in use. If you do not plan to handle these - /// errors you may prefer to use [`fill`]. - /// + + /// Generate a random value in the range [`low`, `high`), i.e. inclusive of + /// `low` and exclusive of `high`. + /// + /// This is a convenience wrapper around + /// `distributions::Range`. If this function will be called + /// repeatedly with the same arguments, one should use `Range`, as + /// that will amortize the computations that allow for perfect + /// uniformity, as they only happen when constructing the `Range`. + /// + /// # Panics + /// + /// Panics if `low >= high`. + /// /// # Example - /// + /// /// ```rust - /// # use rand::Error; /// use rand::{thread_rng, Rng}; - /// - /// # fn try_inner() -> Result<(), Error> { - /// let mut arr = [0u64; 4]; - /// thread_rng().try_fill(&mut arr[..])?; - /// # Ok(()) - /// # } - /// - /// # try_inner().unwrap() + /// + /// let mut rng = thread_rng(); + /// let n: u32 = rng.gen_range(0, 10); + /// println!("{}", n); + /// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64); + /// println!("{}", m); /// ``` - /// - /// [`ErrorKind`]: https://docs.rs/rand_core/0.1/rand_core/enum.ErrorKind.html - /// [`try_fill_bytes`]: https://docs.rs/rand_core/0.1/rand_core/trait.RngCore.html#method.try_fill_bytes - /// [`fill`]: trait.Rng.html#method.fill - /// [`AsByteSliceMut`]: trait.AsByteSliceMut.html - fn try_fill(&mut self, dest: &mut T) -> Result<(), Error> { - self.try_fill_bytes(dest.as_byte_slice_mut())?; - dest.to_le(); - Ok(()) + fn gen_range(&mut self, low: T, high: T) -> T { + Range::sample_single(low, high, self) } - + /// Sample a new value, using the given distribution. - /// + /// /// ### Example - /// + /// /// ```rust /// use rand::{thread_rng, Rng}; /// use rand::distributions::Range; - /// + /// /// let mut rng = thread_rng(); /// let x: i32 = rng.sample(Range::new(10, 15)); /// ``` @@ -414,95 +409,70 @@ pub trait Rng: RngCore { { distr.sample_iter(self) } - - /// Return a random value supporting the [`Uniform`] distribution. - /// - /// [`Uniform`]: distributions/struct.Uniform.html - /// - /// # Example + + /// Fill `dest` entirely with random bytes (uniform value distribution), + /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices + /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.). /// - /// ```rust - /// use rand::{thread_rng, Rng}; + /// On big-endian platforms this performs byte-swapping to ensure + /// portability of results from reproducible generators. /// - /// let mut rng = thread_rng(); - /// let x: u32 = rng.gen(); - /// println!("{}", x); - /// println!("{:?}", rng.gen::<(f64, bool)>()); - /// ``` - #[inline(always)] - fn gen(&mut self) -> T where Uniform: Distribution { - Uniform.sample(self) - } - - /// Return an iterator that will yield an infinite number of randomly - /// generated items. + /// This uses [`fill_bytes`] internally which may handle some RNG errors + /// implicitly (e.g. waiting if the OS generator is not ready), but panics + /// on other errors. See also [`try_fill`] which returns errors. /// /// # Example /// - /// ``` + /// ```rust /// use rand::{thread_rng, Rng}; /// - /// let mut rng = thread_rng(); - /// let x = rng.gen_iter::().take(10).collect::>(); - /// println!("{:?}", x); - /// println!("{:?}", rng.gen_iter::<(f64, bool)>().take(5) - /// .collect::>()); + /// let mut arr = [0i8; 20]; + /// thread_rng().fill(&mut arr[..]); /// ``` - #[allow(deprecated)] - #[deprecated(since="0.5.0", note="use Rng::sample_iter(&Uniform) instead")] - fn gen_iter(&mut self) -> Generator where Uniform: Distribution { - Generator { rng: self, _marker: marker::PhantomData } + /// + /// [`fill_bytes`]: trait.RngCore.html#method.fill_bytes + /// [`try_fill`]: trait.Rng.html#method.try_fill + /// [`AsByteSliceMut`]: trait.AsByteSliceMut.html + fn fill(&mut self, dest: &mut T) { + self.fill_bytes(dest.as_byte_slice_mut()); + dest.to_le(); } - /// Generate a random value in the range [`low`, `high`), i.e. inclusive of - /// `low` and exclusive of `high`. - /// - /// This is a convenience wrapper around - /// `distributions::Range`. If this function will be called - /// repeatedly with the same arguments, one should use `Range`, as - /// that will amortize the computations that allow for perfect - /// uniformity, as they only happen when constructing the `Range`. + /// Fill `dest` entirely with random bytes (uniform value distribution), + /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices + /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.). /// - /// # Panics + /// On big-endian platforms this performs byte-swapping to ensure + /// portability of results from reproducible generators. /// - /// Panics if `low >= high`. + /// This uses [`try_fill_bytes`] internally and forwards all RNG errors. In + /// some cases errors may be resolvable; see [`ErrorKind`] and + /// documentation for the RNG in use. If you do not plan to handle these + /// errors you may prefer to use [`fill`]. /// /// # Example /// /// ```rust + /// # use rand::Error; /// use rand::{thread_rng, Rng}; /// - /// let mut rng = thread_rng(); - /// let n: u32 = rng.gen_range(0, 10); - /// println!("{}", n); - /// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64); - /// println!("{}", m); - /// ``` - fn gen_range(&mut self, low: T, high: T) -> T { - Range::sample_single(low, high, self) - } - - /// Return a bool with a 1 in n chance of true - /// - /// # Example - /// - /// ```rust - /// #[allow(deprecated)] - /// use rand::{thread_rng, Rng}; + /// # fn try_inner() -> Result<(), Error> { + /// let mut arr = [0u64; 4]; + /// thread_rng().try_fill(&mut arr[..])?; + /// # Ok(()) + /// # } /// - /// let mut rng = thread_rng(); - /// assert_eq!(rng.gen_weighted_bool(0), true); - /// assert_eq!(rng.gen_weighted_bool(1), true); - /// // Just like `rng.gen::()` a 50-50% chance, but using a slower - /// // method with different results. - /// println!("{}", rng.gen_weighted_bool(2)); - /// // First meaningful use of `gen_weighted_bool`. - /// println!("{}", rng.gen_weighted_bool(3)); + /// # try_inner().unwrap() /// ``` - #[deprecated(since="0.5.0", note="use gen_bool instead")] - fn gen_weighted_bool(&mut self, n: u32) -> bool { - // Short-circuit after `n <= 1` to avoid panic in `gen_range` - n <= 1 || self.gen_range(0, n) == 0 + /// + /// [`ErrorKind`]: enum.ErrorKind.html + /// [`try_fill_bytes`]: trait.RngCore.html#method.try_fill_bytes + /// [`fill`]: trait.Rng.html#method.fill + /// [`AsByteSliceMut`]: trait.AsByteSliceMut.html + fn try_fill(&mut self, dest: &mut T) -> Result<(), Error> { + self.try_fill_bytes(dest.as_byte_slice_mut())?; + dest.to_le(); + Ok(()) } /// Return a bool with a probability `p` of being true. @@ -532,23 +502,6 @@ pub trait Rng: RngCore { self.gen::() <= p_int } - /// Return an iterator of random characters from the set A-Z,a-z,0-9. - /// - /// # Example - /// - /// ```rust - /// #[allow(deprecated)] - /// use rand::{thread_rng, Rng}; - /// - /// let s: String = thread_rng().gen_ascii_chars().take(10).collect(); - /// println!("{}", s); - /// ``` - #[allow(deprecated)] - #[deprecated(since="0.5.0", note="use sample_iter(&Alphanumeric) instead")] - fn gen_ascii_chars(&mut self) -> AsciiGenerator<&mut Self> { - AsciiGenerator { rng: self } - } - /// Return a random element from `values`. /// /// Return `None` if `values` is empty. @@ -585,7 +538,8 @@ pub trait Rng: RngCore { /// Shuffle a mutable slice in place. /// - /// This applies Durstenfeld's algorithm for the [Fisher–Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm) + /// This applies Durstenfeld's algorithm for the [Fisher–Yates shuffle]( + /// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm) /// which produces an unbiased permutation. /// /// # Example @@ -609,6 +563,67 @@ pub trait Rng: RngCore { values.swap(i, self.gen_range(0, i + 1)); } } + + /// Return an iterator that will yield an infinite number of randomly + /// generated items. + /// + /// # Example + /// + /// ``` + /// # #![allow(deprecated)] + /// use rand::{thread_rng, Rng}; + /// + /// let mut rng = thread_rng(); + /// let x = rng.gen_iter::().take(10).collect::>(); + /// println!("{:?}", x); + /// println!("{:?}", rng.gen_iter::<(f64, bool)>().take(5) + /// .collect::>()); + /// ``` + #[allow(deprecated)] + #[deprecated(since="0.5.0", note="use Rng::sample_iter(&Uniform) instead")] + fn gen_iter(&mut self) -> Generator where Uniform: Distribution { + Generator { rng: self, _marker: marker::PhantomData } + } + + /// Return a bool with a 1 in n chance of true + /// + /// # Example + /// + /// ```rust + /// # #![allow(deprecated)] + /// use rand::{thread_rng, Rng}; + /// + /// let mut rng = thread_rng(); + /// assert_eq!(rng.gen_weighted_bool(0), true); + /// assert_eq!(rng.gen_weighted_bool(1), true); + /// // Just like `rng.gen::()` a 50-50% chance, but using a slower + /// // method with different results. + /// println!("{}", rng.gen_weighted_bool(2)); + /// // First meaningful use of `gen_weighted_bool`. + /// println!("{}", rng.gen_weighted_bool(3)); + /// ``` + #[deprecated(since="0.5.0", note="use gen_bool instead")] + fn gen_weighted_bool(&mut self, n: u32) -> bool { + // Short-circuit after `n <= 1` to avoid panic in `gen_range` + n <= 1 || self.gen_range(0, n) == 0 + } + + /// Return an iterator of random characters from the set A-Z,a-z,0-9. + /// + /// # Example + /// + /// ```rust + /// # #![allow(deprecated)] + /// use rand::{thread_rng, Rng}; + /// + /// let s: String = thread_rng().gen_ascii_chars().take(10).collect(); + /// println!("{}", s); + /// ``` + #[allow(deprecated)] + #[deprecated(since="0.5.0", note="use sample_iter(&Alphanumeric) instead")] + fn gen_ascii_chars(&mut self) -> AsciiGenerator<&mut Self> { + AsciiGenerator { rng: self } + } } impl Rng for R {} @@ -753,7 +768,7 @@ impl Iterator for AsciiGenerator { /// A convenient way to seed new algorithmic generators with fresh entropy from -/// `EntropyRng`. +/// [`EntropyRng`]. /// /// This is the recommended way to create PRNGs, unless a deterministic seed is /// desired (in which case [`SeedableRng::from_seed`] should be used). @@ -770,8 +785,9 @@ impl Iterator for AsciiGenerator { /// println!("Random die roll: {}", rng.gen_range(1, 7)); /// ``` /// -/// [`SeedableRng`]: https://docs.rs/rand_core/0.1/rand_core/trait.SeedableRng.html -/// [`SeedableRng::from_seed`]: https://docs.rs/rand_core/0.1/rand_core/trait.SeedableRng.html#tymethod.from_seed +/// [`EntropyRng`]: struct.EntropyRng.html +/// [`SeedableRng`]: trait.SeedableRng.html +/// [`SeedableRng::from_seed`]: trait.SeedableRng.html#tymethod.from_seed #[cfg(feature="std")] pub trait NewRng: SeedableRng { /// Creates a new instance, automatically seeded with fresh entropy. @@ -782,20 +798,23 @@ pub trait NewRng: SeedableRng { /// almost certainly be platform limitations or build issues, i.e. most /// applications targetting PC/mobile platforms should not need to worry /// about this failing. - /// + /// /// If all entropy sources fail this will panic. If you need to handle /// errors, use the following code, equivalent aside from error handling: - /// + /// /// ```rust - /// use rand::{Rng, StdRng, EntropyRng, SeedableRng, Error}; - /// - /// fn foo() -> Result<(), Error> { - /// // This uses StdRng, but is valid for any R: SeedableRng - /// let mut rng = StdRng::from_rng(EntropyRng::new())?; - /// - /// println!("random number: {}", rng.gen_range(1, 10)); - /// Ok(()) - /// } + /// # use rand::Error; + /// use rand::{Rng, StdRng, EntropyRng, SeedableRng}; + /// + /// # fn try_inner() -> Result<(), Error> { + /// // This uses StdRng, but is valid for any R: SeedableRng + /// let mut rng = StdRng::from_rng(EntropyRng::new())?; + /// + /// println!("random number: {}", rng.gen_range(1, 10)); + /// # Ok(()) + /// # } + /// + /// # try_inner().unwrap() /// ``` fn new() -> Self; } @@ -818,9 +837,10 @@ impl NewRng for R { /// future library versions may use a different internal generator with /// different output. Further, this generator may not be portable and can /// produce different output depending on the architecture. If you require -/// reproducible output, use a named RNG, for example `ChaChaRng`. +/// reproducible output, use a named RNG, for example [`ChaChaRng`]. /// /// [HC-128]: prng/hc128/struct.Hc128Rng.html +/// [`ChaChaRng`]: prng/chacha/struct.ChaChaRng.html #[derive(Clone, Debug)] pub struct StdRng(Hc128Rng); @@ -861,29 +881,31 @@ impl CryptoRng for StdRng {} /// An RNG recommended when small state, cheap initialization and good /// performance are required. The PRNG algorithm in `SmallRng` is chosen to be /// efficient on the current platform, **without consideration for cryptography -/// or security**. The size of its state is much smaller than for `StdRng`. +/// or security**. The size of its state is much smaller than for [`StdRng`]. /// /// Reproducibility of output from this generator is however not required, thus /// future library versions may use a different internal generator with /// different output. Further, this generator may not be portable and can /// produce different output depending on the architecture. If you require -/// reproducible output, use a named RNG, for example `XorShiftRng`. +/// reproducible output, use a named RNG, for example [`XorShiftRng`]. /// /// The current algorithm used on all platforms is [Xorshift]. /// /// # Examples /// -/// Initializing `StdRng` with a random seed can be done using `NewRng`: +/// Initializing `SmallRng` with a random seed can be done using [`NewRng`]: /// /// ``` +/// # use rand::Rng; /// use rand::{NewRng, SmallRng}; /// /// // Create small, cheap to initialize and fast RNG with a random seed. /// // The randomness is supplied by the operating system. /// let mut small_rng = SmallRng::new(); +/// # let v: u32 = small_rng.gen(); /// ``` /// -/// When initializing a lot of `SmallRng`, using `thread_rng` can be more +/// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more /// efficient: /// /// ``` @@ -901,7 +923,11 @@ impl CryptoRng for StdRng {} /// .collect(); /// ``` /// -/// [Xorshift]: struct.XorShiftRng.html +/// [`NewRng`]: trait.NewRng.html +/// [`StdRng`]: struct.StdRng.html +/// [`thread_rng`]: fn.thread_rng.html +/// [Xorshift]: prng/struct.XorShiftRng.html +/// [`XorShiftRng`]: prng/struct.XorShiftRng.html #[derive(Clone, Debug)] pub struct SmallRng(XorShiftRng); @@ -937,7 +963,7 @@ impl SeedableRng for SmallRng { } } -/// DEPRECATED: use `SmallRng` instead. +/// DEPRECATED: use [`SmallRng`] instead. /// /// Create a weak random number generator with a default algorithm and seed. /// @@ -947,6 +973,8 @@ impl SeedableRng for SmallRng { /// create the `Rng` yourself. /// /// This will seed the generator with randomness from `thread_rng`. +/// +/// [`SmallRng`]: struct.SmallRng.html #[deprecated(since="0.5.0", note="removed in favor of SmallRng")] #[cfg(feature="std")] pub fn weak_rng() -> XorShiftRng { @@ -962,6 +990,7 @@ pub fn weak_rng() -> XorShiftRng { /// # Example /// /// ```rust +/// # #![allow(deprecated)] /// use rand::{thread_rng, sample}; /// /// let mut rng = thread_rng(); diff --git a/src/os.rs b/src/os.rs index ef7a74ecfd2..9865738aad6 100644 --- a/src/os.rs +++ b/src/os.rs @@ -15,7 +15,9 @@ use std::fmt; use rand_core::{RngCore, Error, impls}; /// A random number generator that retrieves randomness straight from the -/// operating system. This is the preferred external source of entropy for most +/// operating system. +/// +/// This is the preferred external source of entropy for most /// applications. Commonly it is used to initialize a user-space RNG, which can /// then be used to generate random values with much less overhead than `OsRng`. /// diff --git a/src/prng/chacha.rs b/src/prng/chacha.rs index 83ab395f4a6..76d9049867a 100644 --- a/src/prng/chacha.rs +++ b/src/prng/chacha.rs @@ -108,6 +108,7 @@ impl ChaChaRng { /// # Examples /// /// ```rust + /// # #![allow(deprecated)] /// use rand::{RngCore, ChaChaRng}; /// /// let mut ra = ChaChaRng::new_unseeded(); @@ -140,11 +141,10 @@ impl ChaChaRng { /// # Examples /// /// ```rust - /// use rand::{RngCore, ChaChaRng}; + /// use rand::{ChaChaRng, RngCore, SeedableRng}; /// - /// let mut rng1 = ChaChaRng::new_unseeded(); // Use `ChaChaRng::new()` or - /// // `ChaChaRng::from_rng()` - /// // outside of testing. + /// // Note: Use `NewRng` or `ChaChaRng::from_rng()` outside of testing. + /// let mut rng1 = ChaChaRng::from_seed([0; 32]); /// let mut rng2 = rng1.clone(); /// /// // Skip to round 20. Because every round generates 16 `u32` values, this @@ -168,11 +168,10 @@ impl ChaChaRng { /// # Examples /// /// ```rust - /// use rand::{RngCore, ChaChaRng}; + /// use rand::{ChaChaRng, RngCore, SeedableRng}; /// - /// let mut rng = ChaChaRng::new_unseeded(); // Use `ChaChaRng::new()` or - /// // `ChaChaRng::from_rng()` - /// // outside of testing. + /// // Note: Use `NewRng` or `ChaChaRng::from_rng()` outside of testing. + /// let mut rng = ChaChaRng::from_seed([0; 32]); /// rng.set_rounds(8); /// /// assert_eq!(rng.next_u32(), 0x2fef003e); @@ -183,6 +182,7 @@ impl ChaChaRng { } } +/// The core of `ChaChaRng`, used with `BlockRng`. #[derive(Clone)] pub struct ChaChaCore { state: [u32; STATE_WORDS], diff --git a/src/prng/mod.rs b/src/prng/mod.rs index 0cf0c420f23..edf8f5dffb2 100644 --- a/src/prng/mod.rs +++ b/src/prng/mod.rs @@ -49,8 +49,8 @@ mod xorshift; #[cfg(feature="serde-1")] mod isaac_serde; -pub use self::chacha::ChaChaRng; -pub use self::hc128::Hc128Rng; +#[doc(inline)] pub use self::chacha::ChaChaRng; +#[doc(inline)] pub use self::hc128::Hc128Rng; pub use self::isaac::IsaacRng; pub use self::isaac64::Isaac64Rng; pub use self::xorshift::XorShiftRng; diff --git a/src/read.rs b/src/read.rs index 5157b6d2a23..a6ab6f55a01 100644 --- a/src/read.rs +++ b/src/read.rs @@ -15,8 +15,9 @@ use std::io::Read; use rand_core::{RngCore, Error, ErrorKind, impls}; -/// An RNG that reads random bytes straight from a `Read`. This will -/// work best with an infinite reader, but that is not required. +/// An RNG that reads random bytes straight from a `Read`. +/// +/// This will work best with an infinite reader, but that is not required. /// /// # Panics /// diff --git a/src/thread_rng.rs b/src/thread_rng.rs index bc957a657ce..c849a3bbf7f 100644 --- a/src/thread_rng.rs +++ b/src/thread_rng.rs @@ -45,8 +45,10 @@ use reseeding::ReseedingRng; const THREAD_RNG_RESEED_THRESHOLD: u64 = 32*1024*1024; // 32 MiB /// The type returned by [`thread_rng`], essentially just a reference to the -/// PRNG in thread-local memory. Cloning this handle just produces a new -/// reference to the same thread-local generator. +/// PRNG in thread-local memory. +/// +/// Cloning this handle just produces a new reference to the same thread-local +/// generator. /// /// [`thread_rng`]: fn.thread_rng.html #[derive(Clone, Debug)] @@ -91,7 +93,7 @@ thread_local!( /// [`ReseedingRng`]: reseeding/struct.ReseedingRng.html /// [`StdRng`]: struct.StdRng.html /// [`EntropyRng`]: struct.EntropyRng.html -/// [HC-128]: struct.Hc128Rng.html +/// [HC-128]: prng/hc128/struct.Hc128Rng.html pub fn thread_rng() -> ThreadRng { ThreadRng { rng: THREAD_RNG_KEY.with(|t| t.clone()) } } @@ -129,6 +131,7 @@ impl CryptoRng for ThreadRng {} /// # Examples /// /// ``` +/// # #![allow(deprecated)] /// let x = rand::random::(); /// println!("{}", x); /// @@ -144,6 +147,7 @@ impl CryptoRng for ThreadRng {} /// following example can increase performance. /// /// ``` +/// # #![allow(deprecated)] /// use rand::Rng; /// /// let mut v = vec![1, 2, 3];