Skip to main content

core/
random.rs

1//! Random value generation.
2
3use crate::ops::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 Distribution<u8> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> u8 {
        let mut bytes = (0 as u8).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <u8>::from_ne_bytes(bytes)
    }
}impl_primitive!(u8);
50impl Distribution<i8> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> i8 {
        let mut bytes = (0 as i8).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <i8>::from_ne_bytes(bytes)
    }
}impl_primitive!(i8);
51impl Distribution<u16> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> u16 {
        let mut bytes = (0 as u16).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <u16>::from_ne_bytes(bytes)
    }
}impl_primitive!(u16);
52impl Distribution<i16> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> i16 {
        let mut bytes = (0 as i16).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <i16>::from_ne_bytes(bytes)
    }
}impl_primitive!(i16);
53impl Distribution<u32> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> u32 {
        let mut bytes = (0 as u32).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <u32>::from_ne_bytes(bytes)
    }
}impl_primitive!(u32);
54impl Distribution<i32> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> i32 {
        let mut bytes = (0 as i32).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <i32>::from_ne_bytes(bytes)
    }
}impl_primitive!(i32);
55impl Distribution<u64> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> u64 {
        let mut bytes = (0 as u64).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <u64>::from_ne_bytes(bytes)
    }
}impl_primitive!(u64);
56impl Distribution<i64> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> i64 {
        let mut bytes = (0 as i64).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <i64>::from_ne_bytes(bytes)
    }
}impl_primitive!(i64);
57impl Distribution<u128> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> u128 {
        let mut bytes = (0 as u128).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <u128>::from_ne_bytes(bytes)
    }
}impl_primitive!(u128);
58impl Distribution<i128> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> i128 {
        let mut bytes = (0 as i128).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <i128>::from_ne_bytes(bytes)
    }
}impl_primitive!(i128);
59impl Distribution<usize> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> usize {
        let mut bytes = (0 as usize).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <usize>::from_ne_bytes(bytes)
    }
}impl_primitive!(usize);
60impl Distribution<isize> for RangeFull {
    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> isize {
        let mut bytes = (0 as isize).to_ne_bytes();
        source.fill_bytes(&mut bytes);
        <isize>::from_ne_bytes(bytes)
    }
}impl_primitive!(isize);