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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
extern crate rand;
pub fn petname(words: u8, separator: &str) -> String {
Petnames::default().generate(
&mut rand::thread_rng(), words, separator)
}
pub struct Petnames<'a> {
pub adjectives: Vec<&'a str>,
pub adverbs: Vec<&'a str>,
pub names: Vec<&'a str>,
}
impl<'a> Petnames<'a> {
pub fn default() -> Petnames<'a> {
let adjectives = concat!(
include_str!("../words/large/adjectives.txt"), "\n",
include_str!("../words/medium/adjectives.txt"), "\n",
include_str!("../words/small/adjectives.txt"), "\n",
);
let adverbs = concat!(
include_str!("../words/large/adverbs.txt"), "\n",
include_str!("../words/medium/adverbs.txt"), "\n",
include_str!("../words/small/adverbs.txt"), "\n",
);
let names = concat!(
include_str!("../words/large/names.txt"), "\n",
include_str!("../words/medium/names.txt"), "\n",
include_str!("../words/small/names.txt"), "\n",
);
Self{
adjectives: adjectives.split_whitespace().collect(),
adverbs: adverbs.split_whitespace().collect(),
names: names.split_whitespace().collect(),
}
}
pub fn generate<RNG>(
&self, rng: &mut RNG, words: u8, separator: &str) -> String
where RNG: rand::Rng
{
let mut parts = Vec::with_capacity(words as usize);
for num in (0..words).rev() {
parts.push(*match num {
0 => rng.choose(&self.names).unwrap(),
1 => rng.choose(&self.adjectives).unwrap(),
_ => rng.choose(&self.adverbs).unwrap(),
});
};
parts.join(separator)
}
}
#[cfg(test)]
mod tests {
use super::{petname, Petnames, rand};
#[test]
fn default_petnames_has_adjectives() {
let petnames = Petnames::default();
assert_ne!(petnames.adjectives.len(), 0);
}
#[test]
fn default_petnames_has_adverbs() {
let petnames = Petnames::default();
assert_ne!(petnames.adverbs.len(), 0);
}
#[test]
fn default_petnames_has_names() {
let petnames = Petnames::default();
assert_ne!(petnames.names.len(), 0);
}
#[test]
fn generate_uses_adverb_adjective_name() {
let petnames = Petnames{
adjectives: vec!("adjective"),
adverbs: vec!("adverb"),
names: vec!("name"),
};
assert_eq!(
petnames.generate(&mut rand::thread_rng(), 3, "-"),
"adverb-adjective-name");
}
#[test]
fn petname_renders_desired_number_of_words() {
assert_eq!(petname(7, "-").split("-").count(), 7);
}
#[test]
fn petname_renders_with_desired_separator() {
assert_eq!(petname(7, "@").split("@").count(), 7);
}
}