| 1 | //! Random value generation. |
| 2 | |
| 3 | use crate::ops::RangeFull; |
| 4 | |
| 5 | /// A source of randomness. |
| 6 | #[unstable (feature = "random" , issue = "130703" )] |
| 7 | pub trait RandomSource { |
| 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. |
| 14 | fn fill_bytes(&mut self, bytes: &mut [u8]); |
| 15 | } |
| 16 | |
| 17 | /// A trait representing a distribution of random values for a type. |
| 18 | #[unstable (feature = "random" , issue = "130703" )] |
| 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 | } |
| 28 | } |
| 29 | |
| 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 |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | macro_rules! impl_primitive { |
| 38 | ($t:ty) => { |
| 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(); |
| 42 | source.fill_bytes(&mut bytes); |
| 43 | <$t>::from_ne_bytes(bytes) |
| 44 | } |
| 45 | } |
| 46 | }; |
| 47 | } |
| 48 | |
| 49 | impl_primitive!(u8); |
| 50 | impl_primitive!(i8); |
| 51 | impl_primitive!(u16); |
| 52 | impl_primitive!(i16); |
| 53 | impl_primitive!(u32); |
| 54 | impl_primitive!(i32); |
| 55 | impl_primitive!(u64); |
| 56 | impl_primitive!(i64); |
| 57 | impl_primitive!(u128); |
| 58 | impl_primitive!(i128); |
| 59 | impl_primitive!(usize); |
| 60 | impl_primitive!(isize); |
| 61 | |