core/random.rs
1//! Random value generation.
2
3use crate::range::RangeFull;
4
5/// A source of randomness.
6#[unstable(feature = "random", issue = "130703")]
7pub trait RandomSource {
8 /// Fills `bytes` with random bytes.
9 ///
10 /// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once
11 /// with a larger buffer. A `RandomSource` is allowed to return different bytes for those two
12 /// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw
13 /// part of it away if not needed.
14 fn fill_bytes(&mut self, bytes: &mut [u8]);
15}
16
17/// A trait representing a distribution of random values for a type.
18#[unstable(feature = "random", issue = "130703")]
19pub trait Distribution<T> {
20 /// Samples a random value from the distribution, using the specified random source.
21 fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T;
22}
23
24impl<T, DT: Distribution<T>> Distribution<T> for &DT {
25 fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T {
26 (*self).sample(source)
27 }
28}
29
30impl Distribution<bool> for RangeFull {
31 fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> bool {
32 let byte: u8 = RangeFull.sample(source);
33 byte & 1 == 1
34 }
35}
36
37macro_rules! impl_primitive {
38 ($t:ty) => {
39 impl Distribution<$t> for RangeFull {
40 fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t {
41 let mut bytes = (0 as $t).to_ne_bytes();
42 source.fill_bytes(&mut bytes);
43 <$t>::from_ne_bytes(bytes)
44 }
45 }
46 };
47}
48
49impl_primitive!(u8);
50impl_primitive!(i8);
51impl_primitive!(u16);
52impl_primitive!(i16);
53impl_primitive!(u32);
54impl_primitive!(i32);
55impl_primitive!(u64);
56impl_primitive!(i64);
57impl_primitive!(u128);
58impl_primitive!(i128);
59impl_primitive!(usize);
60impl_primitive!(isize);