1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
mod words;
pub const WORDS: &[&str] = words::LIST;
const NUM_BITS: usize = 13;
fn words_for_bits(bits: usize) -> impl Iterator<Item=&'static str> {
use rand::Rng;
let num_words = if bits % NUM_BITS == 0 { bits/NUM_BITS } else { bits/NUM_BITS + 1 };
let number_per_word = (bits as f64/num_words as f64).exp2() as usize;
let mut words = Vec::with_capacity(num_words);
let mut rng = rand::thread_rng();
for _ in 0..num_words {
words.push(rng.choose(&WORDS[0..number_per_word]).unwrap());
}
words.into_iter().map(|&x| x)
}
pub fn space_delimited(bits: usize) -> String {
let mut code = String::new();
for w in words_for_bits(bits) {
code.push_str(w);
code.push(' ');
}
code.pop();
code
}
pub fn snake_case(bits: usize) -> String {
let mut code = String::new();
for w in words_for_bits(bits) {
code.push_str(w);
code.push('_');
}
code.pop();
code
}
pub fn kebab_case(bits: usize) -> String {
let mut code = String::new();
for w in words_for_bits(bits) {
code.push_str(w);
code.push('-');
}
code.pop();
code
}
pub fn camel_case(bits: usize) -> String {
let mut code = String::new();
for w in words_for_bits(bits) {
let mut c = w.chars();
code.push(c.next().unwrap().to_uppercase().next().unwrap());
code.push_str(c.as_str());
}
code
}
#[test]
fn has_length() {
assert!(space_delimited(41).len() > 4);
assert!(snake_case(40).len() > 4);
assert!(camel_case(40).len() > 4);
assert!(kebab_case(40).len() > 4);
}
#[test]
fn num_bits_correct() {
assert!(1 << NUM_BITS <= WORDS.len());
}