| //! Random value generation. | |
| use crate::ops::RangeFull; | |
| /// A source of randomness. | |
| #[unstable(feature = "random", issue = "130703")] | |
| pub trait RandomSource { | |
| /// Fills `bytes` with random bytes. | |
| /// | |
| /// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once | |
| /// with a larger buffer. A `RandomSource` is allowed to return different bytes for those two | |
| /// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw | |
| /// part of it away if not needed. | |
| fn fill_bytes(&mut self, bytes: &mut [u8]); | |
| } | |
| /// A trait representing a distribution of random values for a type. | |
| #[unstable(feature = "random", issue = "130703")] | |
| pub trait Distribution<T> { | |
| /// Samples a random value from the distribution, using the specified random source. | |
| fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T; | |
| } | |
| impl<T, DT: Distribution<T>> Distribution<T> for &DT { | |
| fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T { | |
| (*self).sample(source) | |
| } | |
| } | |
| impl Distribution<bool> for RangeFull { | |
| fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> bool { | |
| let byte: u8 = RangeFull.sample(source); | |
| byte & 1 == 1 | |
| } | |
| } | |
| macro_rules! impl_primitive { | |
| ($t:ty) => { | |
| impl Distribution<$t> for RangeFull { | |
| fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t { | |
| let mut bytes = (0 as $t).to_ne_bytes(); | |
| source.fill_bytes(&mut bytes); | |
| <$t>::from_ne_bytes(bytes) | |
| } | |
| } | |
| }; | |
| } | |
| impl_primitive!(u8); | |
| impl_primitive!(i8); | |
| impl_primitive!(u16); | |
| impl_primitive!(i16); | |
| impl_primitive!(u32); | |
| impl_primitive!(i32); | |
| impl_primitive!(u64); | |
| impl_primitive!(i64); | |
| impl_primitive!(u128); | |
| impl_primitive!(i128); | |
| impl_primitive!(usize); | |
| impl_primitive!(isize); |