core/
random.rs

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")]
8pub 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")]
21pub trait Random: Sized {
22    /// Generates a random value.
23    fn random(source: &mut (impl RandomSource + ?Sized)) -> Self;
24}
25
26impl Random for bool {
27    fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
28        u8::random(source) & 1 == 1
29    }
30}
31
32macro_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
51impl_primitive!(u8);
52impl_primitive!(i8);
53impl_primitive!(u16);
54impl_primitive!(i16);
55impl_primitive!(u32);
56impl_primitive!(i32);
57impl_primitive!(u64);
58impl_primitive!(i64);
59impl_primitive!(u128);
60impl_primitive!(i128);
61impl_primitive!(usize);
62impl_primitive!(isize);