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