1use std::collections::HashSet;
10
11use rand::{Rng, rngs::ThreadRng, thread_rng};
12
13const LEFT_NAMES: [&str; 108] = [
15 "admiring",
16 "adoring",
17 "affectionate",
18 "agitated",
19 "amazing",
20 "angry",
21 "awesome",
22 "beautiful",
23 "blissful",
24 "bold",
25 "boring",
26 "brave",
27 "busy",
28 "charming",
29 "clever",
30 "compassionate",
31 "competent",
32 "condescending",
33 "confident",
34 "cool",
35 "cranky",
36 "crazy",
37 "dazzling",
38 "determined",
39 "distracted",
40 "dreamy",
41 "eager",
42 "ecstatic",
43 "elastic",
44 "elated",
45 "elegant",
46 "eloquent",
47 "epic",
48 "exciting",
49 "fervent",
50 "festive",
51 "flamboyant",
52 "focused",
53 "friendly",
54 "frosty",
55 "funny",
56 "gallant",
57 "gifted",
58 "goofy",
59 "gracious",
60 "great",
61 "happy",
62 "hardcore",
63 "heuristic",
64 "hopeful",
65 "hungry",
66 "infallible",
67 "inspiring",
68 "intelligent",
69 "interesting",
70 "jolly",
71 "jovial",
72 "keen",
73 "kind",
74 "laughing",
75 "loving",
76 "lucid",
77 "magical",
78 "modest",
79 "musing",
80 "mystifying",
81 "naughty",
82 "nervous",
83 "nice",
84 "nifty",
85 "nostalgic",
86 "objective",
87 "optimistic",
88 "peaceful",
89 "pedantic",
90 "pensive",
91 "practical",
92 "priceless",
93 "quirky",
94 "quizzical",
95 "recursing",
96 "relaxed",
97 "reverent",
98 "romantic",
99 "sad",
100 "serene",
101 "sharp",
102 "silly",
103 "sleepy",
104 "stoic",
105 "strange",
106 "stupefied",
107 "suspicious",
108 "sweet",
109 "tender",
110 "thirsty",
111 "trusting",
112 "unruffled",
113 "upbeat",
114 "vibrant",
115 "vigilant",
116 "vigorous",
117 "wizardly",
118 "wonderful",
119 "xenodochial",
120 "youthful",
121 "zealous",
122 "zen",
123];
124
125const LEFT_LENGTH: usize = LEFT_NAMES.len();
126
127const RIGHT_NAMES: [&str; 53] = [
129 "agates",
130 "alexandrite",
131 "amber",
132 "amethyst",
133 "apatite",
134 "avanturine",
135 "axinite",
136 "beryl",
137 "beryl",
138 "carnelian",
139 "chalcedony",
140 "chrysoberyl",
141 "chrysolite",
142 "chrysoprase",
143 "coral",
144 "corundum",
145 "crocidolite",
146 "cyanite",
147 "cymophane",
148 "diamond",
149 "dichroite",
150 "emerald",
151 "epidote",
152 "euclase",
153 "felspar",
154 "garnet",
155 "heliotrope",
156 "hematite",
157 "hiddenite",
158 "hypersthene",
159 "idocrase",
160 "jasper",
161 "jet",
162 "labradorite",
163 "malachite",
164 "moonstone",
165 "obsidian",
166 "opal",
167 "pearl",
168 "phenacite",
169 "plasma",
170 "prase",
171 "quartz",
172 "ruby",
173 "sapphire",
174 "sphene",
175 "spinel",
176 "spodumene",
177 "sunstone",
178 "topaz",
179 "tourmaline",
180 "turquois",
181 "zircon",
182];
183const RIGHT_LENGTH: usize = RIGHT_NAMES.len();
184
185pub fn random_name(conflicts: &HashSet<String>) -> String {
190 let mut rng = thread_rng();
191 loop {
194 let output = generate(&mut rng);
195 if !conflicts.contains(&output) {
196 return output;
197 }
198 }
199}
200
201pub fn random_names(mut conflicts: HashSet<String>, output_size: usize) -> Vec<String> {
203 let mut names = Vec::with_capacity(output_size);
204 names.resize_with(output_size, || {
205 let name = random_name(&conflicts);
206 conflicts.insert(name.clone());
207 name
208 });
209 names
210}
211
212fn generate(rng: &mut ThreadRng) -> String {
214 let left_idx = rng.gen_range(0..LEFT_LENGTH);
215 let right_idx = rng.gen_range(0..RIGHT_LENGTH);
216 format!(
217 "{}-{}",
218 LEFT_NAMES.get(left_idx).unwrap(),
219 RIGHT_NAMES.get(right_idx).unwrap()
220 )
221}