|  | 
| 1 | 1 | //! Random value generation. | 
| 2 |  | -//! | 
| 3 |  | -//! The [`Random`] trait allows generating a random value for a type using a | 
| 4 |  | -//! given [`RandomSource`]. | 
|  | 2 | +
 | 
|  | 3 | +use crate::range::RangeFull; | 
| 5 | 4 | 
 | 
| 6 | 5 | /// A source of randomness. | 
| 7 | 6 | #[unstable(feature = "random", issue = "130703")] | 
| 8 | 7 | pub trait RandomSource { | 
| 9 | 8 |     /// Fills `bytes` with random bytes. | 
|  | 9 | +    /// | 
|  | 10 | +    /// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once | 
|  | 11 | +    /// with a larger buffer. A `RandomSource` is allowed to return different bytes for those two | 
|  | 12 | +    /// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw | 
|  | 13 | +    /// part of it away if not needed. | 
| 10 | 14 |     fn fill_bytes(&mut self, bytes: &mut [u8]); | 
| 11 | 15 | } | 
| 12 | 16 | 
 | 
| 13 |  | -/// A trait for getting a random value for a type. | 
| 14 |  | -/// | 
| 15 |  | -/// **Warning:** Be careful when manipulating random values! The | 
| 16 |  | -/// [`random`](Random::random) method on integers samples them with a uniform | 
| 17 |  | -/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using | 
| 18 |  | -/// modulo operations, some of the resulting values can become more likely than | 
| 19 |  | -/// others. Use audited crates when in doubt. | 
|  | 17 | +/// A trait representing a distribution of random values for a type. | 
| 20 | 18 | #[unstable(feature = "random", issue = "130703")] | 
| 21 |  | -pub trait Random: Sized { | 
| 22 |  | -    /// Generates a random value. | 
| 23 |  | -    fn random(source: &mut (impl RandomSource + ?Sized)) -> Self; | 
|  | 19 | +pub trait Distribution<T> { | 
|  | 20 | +    /// Samples a random value from the distribution, using the specified random source. | 
|  | 21 | +    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T; | 
|  | 22 | +} | 
|  | 23 | + | 
|  | 24 | +impl<T, DT: Distribution<T>> Distribution<T> for &DT { | 
|  | 25 | +    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T { | 
|  | 26 | +        (*self).sample(source) | 
|  | 27 | +    } | 
| 24 | 28 | } | 
| 25 | 29 | 
 | 
| 26 |  | -impl Random for bool { | 
| 27 |  | -    fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { | 
| 28 |  | -        u8::random(source) & 1 == 1 | 
|  | 30 | +impl Distribution<bool> for RangeFull { | 
|  | 31 | +    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> bool { | 
|  | 32 | +        let byte: u8 = RangeFull.sample(source); | 
|  | 33 | +        byte & 1 == 1 | 
| 29 | 34 |     } | 
| 30 | 35 | } | 
| 31 | 36 | 
 | 
| 32 | 37 | macro_rules! impl_primitive { | 
| 33 | 38 |     ($t:ty) => { | 
| 34 |  | -        impl Random for $t { | 
| 35 |  | -            /// Generates a random value. | 
| 36 |  | -            /// | 
| 37 |  | -            /// **Warning:** Be careful when manipulating the resulting value! This | 
| 38 |  | -            /// method samples according to a uniform distribution, so a value of 1 is | 
| 39 |  | -            /// just as likely as [`MAX`](Self::MAX). By using modulo operations, some | 
| 40 |  | -            /// values can become more likely than others. Use audited crates when in | 
| 41 |  | -            /// doubt. | 
| 42 |  | -            fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { | 
| 43 |  | -                let mut bytes = (0 as Self).to_ne_bytes(); | 
|  | 39 | +        impl Distribution<$t> for RangeFull { | 
|  | 40 | +            fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t { | 
|  | 41 | +                let mut bytes = (0 as $t).to_ne_bytes(); | 
| 44 | 42 |                 source.fill_bytes(&mut bytes); | 
| 45 |  | -                Self::from_ne_bytes(bytes) | 
|  | 43 | +                <$t>::from_ne_bytes(bytes) | 
| 46 | 44 |             } | 
| 47 | 45 |         } | 
| 48 | 46 |     }; | 
|  | 
0 commit comments