33//! The [`Random`] trait allows generating a random value for a type using a
44//! given [`RandomSource`].
55
6+ use crate :: range:: RangeFull ;
7+
68/// A source of randomness.
79#[ unstable( feature = "random" , issue = "130703" ) ]
810pub trait RandomSource {
@@ -15,39 +17,33 @@ pub trait RandomSource {
1517 fn fill_bytes ( & mut self , bytes : & mut [ u8 ] ) ;
1618}
1719
18- /// A trait for getting a random value for a type.
19- ///
20- /// **Warning:** Be careful when manipulating random values! The
21- /// [`random`](Random::random) method on integers samples them with a uniform
22- /// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using
23- /// modulo operations, some of the resulting values can become more likely than
24- /// others. Use audited crates when in doubt.
20+ /// A trait representing a distribution of random values for a type.
2521#[ unstable( feature = "random" , issue = "130703" ) ]
26- pub trait Random : Sized {
27- /// Generates a random value.
28- fn random ( source : & mut ( impl RandomSource + ?Sized ) ) -> Self ;
22+ pub trait Distribution < T > {
23+ /// Samples a random value from the distribution, using the specified random source.
24+ fn sample ( & self , source : & mut ( impl RandomSource + ?Sized ) ) -> T ;
25+ }
26+
27+ impl < T , DT : Distribution < T > > Distribution < T > for & DT {
28+ fn sample ( & self , source : & mut ( impl RandomSource + ?Sized ) ) -> T {
29+ ( * self ) . sample ( source)
30+ }
2931}
3032
31- impl Random for bool {
32- fn random ( source : & mut ( impl RandomSource + ?Sized ) ) -> Self {
33- u8:: random ( source) & 1 == 1
33+ impl Distribution < bool > for RangeFull {
34+ fn sample ( & self , source : & mut ( impl RandomSource + ?Sized ) ) -> bool {
35+ let byte: u8 = RangeFull . sample ( source) ;
36+ byte & 1 == 1
3437 }
3538}
3639
3740macro_rules! impl_primitive {
3841 ( $t: ty) => {
39- impl Random for $t {
40- /// Generates a random value.
41- ///
42- /// **Warning:** Be careful when manipulating the resulting value! This
43- /// method samples according to a uniform distribution, so a value of 1 is
44- /// just as likely as [`MAX`](Self::MAX). By using modulo operations, some
45- /// values can become more likely than others. Use audited crates when in
46- /// doubt.
47- fn random( source: & mut ( impl RandomSource + ?Sized ) ) -> Self {
48- let mut bytes = ( 0 as Self ) . to_ne_bytes( ) ;
42+ impl Distribution <$t> for RangeFull {
43+ fn sample( & self , source: & mut ( impl RandomSource + ?Sized ) ) -> $t {
44+ let mut bytes = ( 0 as $t) . to_ne_bytes( ) ;
4945 source. fill_bytes( & mut bytes) ;
50- Self :: from_ne_bytes( bytes)
46+ <$t> :: from_ne_bytes( bytes)
5147 }
5248 }
5349 } ;
0 commit comments