| 1 | //! Random value generation. |
| 2 | //! |
| 3 | //! The [`Random`] trait allows generating a random value for a type using a |
| 4 | //! given [`RandomSource`]. |
| 5 | |
| 6 | /// A source of randomness. |
| 7 | #[unstable (feature = "random" , issue = "130703" )] |
| 8 | pub trait RandomSource { |
| 9 | /// Fills `bytes` with random bytes. |
| 10 | fn fill_bytes(&mut self, bytes: &mut [u8]); |
| 11 | } |
| 12 | |
| 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. |
| 20 | #[unstable (feature = "random" , issue = "130703" )] |
| 21 | pub trait Random: Sized { |
| 22 | /// Generates a random value. |
| 23 | fn random(source: &mut (impl RandomSource + ?Sized)) -> Self; |
| 24 | } |
| 25 | |
| 26 | impl Random for bool { |
| 27 | fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { |
| 28 | u8::random(source) & 1 == 1 |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | macro_rules! impl_primitive { |
| 33 | ($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(); |
| 44 | source.fill_bytes(&mut bytes); |
| 45 | Self::from_ne_bytes(bytes) |
| 46 | } |
| 47 | } |
| 48 | }; |
| 49 | } |
| 50 | |
| 51 | impl_primitive!(u8); |
| 52 | impl_primitive!(i8); |
| 53 | impl_primitive!(u16); |
| 54 | impl_primitive!(i16); |
| 55 | impl_primitive!(u32); |
| 56 | impl_primitive!(i32); |
| 57 | impl_primitive!(u64); |
| 58 | impl_primitive!(i64); |
| 59 | impl_primitive!(u128); |
| 60 | impl_primitive!(i128); |
| 61 | impl_primitive!(usize); |
| 62 | impl_primitive!(isize); |
| 63 | |