1#[derive(Debug, Clone, Copy)]
6pub struct SeedAddress {
7 pub strasse: &'static str,
8 pub hausnummer: &'static str,
9 pub plz: &'static str,
10 pub ort: &'static str,
11 pub bundesland: &'static str,
12}
13
14pub static NACHNAMEN: &[&str] = &[
16 "Mueller",
17 "Schmidt",
18 "Schneider",
19 "Fischer",
20 "Weber",
21 "Meyer",
22 "Wagner",
23 "Becker",
24 "Schulz",
25 "Hoffmann",
26 "Koch",
27 "Richter",
28 "Klein",
29 "Wolf",
30 "Schroeder",
31 "Neumann",
32 "Braun",
33 "Zimmermann",
34 "Hartmann",
35 "Lange",
36];
37
38pub static VORNAMEN: &[&str] = &[
40 "Anna",
41 "Thomas",
42 "Maria",
43 "Michael",
44 "Julia",
45 "Andreas",
46 "Katharina",
47 "Stefan",
48 "Laura",
49 "Markus",
50 "Sarah",
51 "Christian",
52 "Lisa",
53 "Daniel",
54 "Sophie",
55 "Matthias",
56 "Lena",
57 "Martin",
58 "Hannah",
59 "Jan",
60];
61
62pub static ANREDEN: &[&str] = &["Herr", "Frau"];
64
65pub static TITEL: &[&str] = &["", "", "", "", "", "Dr.", "Prof.", "Dr.-Ing."];
67
68pub static ADDRESSES: &[SeedAddress] = &[
73 SeedAddress {
75 strasse: "Unter den Linden",
76 hausnummer: "12",
77 plz: "10117",
78 ort: "Berlin",
79 bundesland: "BE",
80 },
81 SeedAddress {
82 strasse: "Kurfuerstendamm",
83 hausnummer: "195",
84 plz: "10707",
85 ort: "Berlin",
86 bundesland: "BE",
87 },
88 SeedAddress {
89 strasse: "Friedrichstrasse",
90 hausnummer: "43",
91 plz: "10969",
92 ort: "Berlin",
93 bundesland: "BE",
94 },
95 SeedAddress {
97 strasse: "Maximilianstrasse",
98 hausnummer: "8",
99 plz: "80539",
100 ort: "Muenchen",
101 bundesland: "BY",
102 },
103 SeedAddress {
104 strasse: "Ludwigstrasse",
105 hausnummer: "28",
106 plz: "80539",
107 ort: "Muenchen",
108 bundesland: "BY",
109 },
110 SeedAddress {
111 strasse: "Koenigsstrasse",
112 hausnummer: "55",
113 plz: "90402",
114 ort: "Nuernberg",
115 bundesland: "BY",
116 },
117 SeedAddress {
119 strasse: "Schildergasse",
120 hausnummer: "72",
121 plz: "50667",
122 ort: "Koeln",
123 bundesland: "NW",
124 },
125 SeedAddress {
126 strasse: "Koenigsallee",
127 hausnummer: "30",
128 plz: "40212",
129 ort: "Duesseldorf",
130 bundesland: "NW",
131 },
132 SeedAddress {
133 strasse: "Westendhellweg",
134 hausnummer: "1",
135 plz: "44137",
136 ort: "Dortmund",
137 bundesland: "NW",
138 },
139 SeedAddress {
140 strasse: "Limbecker Platz",
141 hausnummer: "5",
142 plz: "45127",
143 ort: "Essen",
144 bundesland: "NW",
145 },
146 SeedAddress {
148 strasse: "Jungfernstieg",
149 hausnummer: "7",
150 plz: "20354",
151 ort: "Hamburg",
152 bundesland: "HH",
153 },
154 SeedAddress {
155 strasse: "Moenckebergstrasse",
156 hausnummer: "21",
157 plz: "20095",
158 ort: "Hamburg",
159 bundesland: "HH",
160 },
161 SeedAddress {
163 strasse: "Zeil",
164 hausnummer: "106",
165 plz: "60313",
166 ort: "Frankfurt am Main",
167 bundesland: "HE",
168 },
169 SeedAddress {
170 strasse: "Luisenplatz",
171 hausnummer: "3",
172 plz: "64283",
173 ort: "Darmstadt",
174 bundesland: "HE",
175 },
176 SeedAddress {
178 strasse: "Georgstrasse",
179 hausnummer: "14",
180 plz: "30159",
181 ort: "Hannover",
182 bundesland: "NI",
183 },
184 SeedAddress {
185 strasse: "Schlosswall",
186 hausnummer: "10",
187 plz: "38100",
188 ort: "Braunschweig",
189 bundesland: "NI",
190 },
191 SeedAddress {
193 strasse: "Koenigstrasse",
194 hausnummer: "26",
195 plz: "70173",
196 ort: "Stuttgart",
197 bundesland: "BW",
198 },
199 SeedAddress {
200 strasse: "Hauptstrasse",
201 hausnummer: "120",
202 plz: "69117",
203 ort: "Heidelberg",
204 bundesland: "BW",
205 },
206 SeedAddress {
208 strasse: "Grimmaische Strasse",
209 hausnummer: "2",
210 plz: "04109",
211 ort: "Leipzig",
212 bundesland: "SN",
213 },
214 SeedAddress {
215 strasse: "Prager Strasse",
216 hausnummer: "15",
217 plz: "01069",
218 ort: "Dresden",
219 bundesland: "SN",
220 },
221 SeedAddress {
223 strasse: "Obernstrasse",
224 hausnummer: "33",
225 plz: "28195",
226 ort: "Bremen",
227 bundesland: "HB",
228 },
229 SeedAddress {
231 strasse: "Holstenstrasse",
232 hausnummer: "43",
233 plz: "24103",
234 ort: "Kiel",
235 bundesland: "SH",
236 },
237 SeedAddress {
239 strasse: "Anger",
240 hausnummer: "18",
241 plz: "99084",
242 ort: "Erfurt",
243 bundesland: "TH",
244 },
245 SeedAddress {
246 strasse: "Schillerstrasse",
247 hausnummer: "4",
248 plz: "99423",
249 ort: "Weimar",
250 bundesland: "TH",
251 },
252 SeedAddress {
254 strasse: "Brandenburger Strasse",
255 hausnummer: "9",
256 plz: "14467",
257 ort: "Potsdam",
258 bundesland: "BB",
259 },
260 SeedAddress {
262 strasse: "Ludwigstrasse",
263 hausnummer: "15",
264 plz: "55116",
265 ort: "Mainz",
266 bundesland: "RP",
267 },
268 SeedAddress {
269 strasse: "Sternstrasse",
270 hausnummer: "22",
271 plz: "56068",
272 ort: "Koblenz",
273 bundesland: "RP",
274 },
275 SeedAddress {
277 strasse: "Grosse Ulrichstrasse",
278 hausnummer: "51",
279 plz: "06108",
280 ort: "Halle",
281 bundesland: "ST",
282 },
283 SeedAddress {
285 strasse: "Kroepeliner Strasse",
286 hausnummer: "38",
287 plz: "18055",
288 ort: "Rostock",
289 bundesland: "MV",
290 },
291 SeedAddress {
293 strasse: "Bahnhofstrasse",
294 hausnummer: "67",
295 plz: "66111",
296 ort: "Saarbruecken",
297 bundesland: "SL",
298 },
299];
300
301pub fn pick<T>(items: &[T], seed: u64) -> &T {
305 &items[pick_index(items.len(), seed)]
306}
307
308pub fn pick_index(len: usize, seed: u64) -> usize {
313 assert!(len > 0, "pick_index: slice must not be empty");
314 (seed as usize) % len
315}
316
317pub fn pick_address(seed: u64) -> &'static SeedAddress {
319 &ADDRESSES[pick_index(ADDRESSES.len(), seed)]
320}
321
322#[cfg(test)]
323mod tests {
324 use super::*;
325
326 #[test]
327 fn test_nachnamen_non_empty() {
328 assert!(!NACHNAMEN.is_empty());
329 assert_eq!(NACHNAMEN.len(), 20);
330 }
331
332 #[test]
333 fn test_vornamen_non_empty() {
334 assert!(!VORNAMEN.is_empty());
335 assert_eq!(VORNAMEN.len(), 20);
336 }
337
338 #[test]
339 fn test_anreden_non_empty() {
340 assert!(!ANREDEN.is_empty());
341 assert_eq!(ANREDEN.len(), 2);
342 }
343
344 #[test]
345 fn test_titel_non_empty() {
346 assert!(!TITEL.is_empty());
347 assert_eq!(TITEL.len(), 8);
348 }
349
350 #[test]
351 fn test_addresses_non_empty() {
352 assert!(!ADDRESSES.is_empty());
353 assert_eq!(ADDRESSES.len(), 30);
354 }
355
356 #[test]
357 fn test_all_addresses_have_five_digit_plz() {
358 for (i, addr) in ADDRESSES.iter().enumerate() {
359 assert_eq!(
360 addr.plz.len(),
361 5,
362 "Address {} ({}) has PLZ '{}' which is not 5 digits",
363 i,
364 addr.ort,
365 addr.plz
366 );
367 assert!(
368 addr.plz.chars().all(|c| c.is_ascii_digit()),
369 "Address {} ({}) has non-digit PLZ '{}'",
370 i,
371 addr.ort,
372 addr.plz
373 );
374 }
375 }
376
377 #[test]
378 fn test_all_addresses_have_two_char_bundesland() {
379 for (i, addr) in ADDRESSES.iter().enumerate() {
380 assert_eq!(
381 addr.bundesland.len(),
382 2,
383 "Address {} ({}) has Bundesland '{}' which is not 2 chars",
384 i,
385 addr.ort,
386 addr.bundesland
387 );
388 }
389 }
390
391 #[test]
392 fn test_all_addresses_have_non_empty_fields() {
393 for (i, addr) in ADDRESSES.iter().enumerate() {
394 assert!(!addr.strasse.is_empty(), "Address {} has empty strasse", i);
395 assert!(
396 !addr.hausnummer.is_empty(),
397 "Address {} has empty hausnummer",
398 i
399 );
400 assert!(!addr.ort.is_empty(), "Address {} has empty ort", i);
401 }
402 }
403
404 #[test]
405 fn test_pick_is_deterministic() {
406 let a = pick(NACHNAMEN, 42);
407 let b = pick(NACHNAMEN, 42);
408 assert_eq!(a, b, "pick must return the same value for the same seed");
409
410 let c = pick(VORNAMEN, 123);
411 let d = pick(VORNAMEN, 123);
412 assert_eq!(c, d, "pick must return the same value for the same seed");
413
414 let e = pick(ADDRESSES, 7);
415 let f = pick(ADDRESSES, 7);
416 assert_eq!(
417 e.plz, f.plz,
418 "pick must return the same address for the same seed"
419 );
420 }
421
422 #[test]
423 fn test_pick_different_seeds_vary() {
424 let a = pick(NACHNAMEN, 0);
427 let b = pick(NACHNAMEN, 7);
428 assert!(!a.is_empty());
430 assert!(!b.is_empty());
431 }
432
433 #[test]
434 fn test_pick_index_deterministic() {
435 let a = pick_index(30, 42);
436 let b = pick_index(30, 42);
437 assert_eq!(a, b);
438 }
439
440 #[test]
441 fn test_pick_index_in_range() {
442 for seed in 0..100 {
443 let idx = pick_index(30, seed);
444 assert!(
445 idx < 30,
446 "pick_index({}, {}) = {} which is out of range",
447 30,
448 seed,
449 idx
450 );
451 }
452 }
453
454 #[test]
455 #[should_panic(expected = "pick_index: slice must not be empty")]
456 fn test_pick_index_panics_on_empty() {
457 pick_index(0, 42);
458 }
459}