@@ -15,6 +15,31 @@ use core::char;
15
15
use { Rng } ;
16
16
use distributions:: { Distribution , Uniform } ;
17
17
18
+ // ----- Sampling distributions -----
19
+
20
+ /// Sample a `char`, uniformly distributed over ASCII letters and numbers:
21
+ /// a-z, A-Z and 0-9.
22
+ ///
23
+ /// # Example
24
+ ///
25
+ /// ```rust
26
+ /// use std::iter;
27
+ /// use rand::{Rng, thread_rng};
28
+ /// use rand::distributions::Alphanumeric;
29
+ ///
30
+ /// let mut rng = thread_rng();
31
+ /// let chars: String = iter::repeat(())
32
+ /// .map(|()| rng.sample(Alphanumeric))
33
+ /// .take(7)
34
+ /// .collect();
35
+ /// println!("Random chars: {}", chars);
36
+ /// ```
37
+ #[ derive( Debug ) ]
38
+ pub struct Alphanumeric ;
39
+
40
+
41
+ // ----- Implementations of distributions -----
42
+
18
43
impl Distribution < char > for Uniform {
19
44
#[ inline]
20
45
fn sample < R : Rng + ?Sized > ( & self , rng : & mut R ) -> char {
@@ -32,6 +57,22 @@ impl Distribution<char> for Uniform {
32
57
}
33
58
}
34
59
60
+ impl Distribution < char > for Alphanumeric {
61
+ fn sample < R : Rng + ?Sized > ( & self , rng : & mut R ) -> char {
62
+ const RANGE : u32 = 26 + 26 + 10 ;
63
+ const GEN_ASCII_STR_CHARSET : & ' static [ u8 ] =
64
+ b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
65
+ abcdefghijklmnopqrstuvwxyz\
66
+ 0123456789";
67
+ loop {
68
+ let var = rng. next_u32 ( ) >> 26 ;
69
+ if var < RANGE {
70
+ return GEN_ASCII_STR_CHARSET [ var as usize ] as char
71
+ }
72
+ }
73
+ }
74
+ }
75
+
35
76
impl Distribution < bool > for Uniform {
36
77
#[ inline]
37
78
fn sample < R : Rng + ?Sized > ( & self , rng : & mut R ) -> bool {
@@ -118,6 +159,7 @@ impl<T> Distribution<Option<T>> for Uniform where Uniform: Distribution<T> {
118
159
#[ cfg( test) ]
119
160
mod tests {
120
161
use { Rng , RngCore , Uniform } ;
162
+ #[ cfg( all( not( feature="std" ) , feature="alloc" ) ) ] use alloc:: String ;
121
163
122
164
#[ test]
123
165
fn test_misc ( ) {
@@ -126,4 +168,19 @@ mod tests {
126
168
rng. sample :: < char , _ > ( Uniform ) ;
127
169
rng. sample :: < bool , _ > ( Uniform ) ;
128
170
}
171
+
172
+ #[ cfg( any( feature="std" , feature="alloc" ) ) ]
173
+ #[ test]
174
+ fn test_chars ( ) {
175
+ use core:: iter;
176
+ use distributions:: Alphanumeric ;
177
+ let mut rng = :: test:: rng ( 805 ) ;
178
+
179
+ let c = rng. sample ( Alphanumeric ) ;
180
+ assert ! ( ( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) ) ;
181
+
182
+ let word: String = iter:: repeat ( ( ) )
183
+ . map ( |( ) | rng. sample ( Alphanumeric ) ) . take ( 5 ) . collect ( ) ;
184
+ assert_eq ! ( word. len( ) , 5 ) ;
185
+ }
129
186
}
0 commit comments