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);