//! Random value generation. //! //! The [`Random`] trait allows generating a random value for a type using a //! given [`RandomSource`]. /// A source of randomness. #[unstable(feature = "random", issue = "130703")] pub trait RandomSource { /// Fills `bytes` with random bytes. fn fill_bytes(&mut self, bytes: &mut [u8]); } /// A trait for getting a random value for a type. /// /// **Warning:** Be careful when manipulating random values! The /// [`random`](Random::random) method on integers samples them with a uniform /// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using /// modulo operations, some of the resulting values can become more likely than /// others. Use audited crates when in doubt. #[unstable(feature = "random", issue = "130703")] pub trait Random: Sized { /// Generates a random value. fn random(source: &mut (impl RandomSource + ?Sized)) -> Self; } impl Random for bool { fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { u8::random(source) & 1 == 1 } } macro_rules! impl_primitive { ($t:ty) => { impl Random for $t { /// Generates a random value. /// /// **Warning:** Be careful when manipulating the resulting value! This /// method samples according to a uniform distribution, so a value of 1 is /// just as likely as [`MAX`](Self::MAX). By using modulo operations, some /// values can become more likely than others. Use audited crates when in /// doubt. fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { let mut bytes = (0 as Self).to_ne_bytes(); source.fill_bytes(&mut bytes); Self::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);