1use std::{
2 collections::{
3 btree_map::{self, BTreeMap},
4 HashMap,
5 },
6 io::BufRead,
7 iter::Iterator,
8 path::Path,
9};
10
11use crate::{
12 error::Error,
13 model::{
14 datensatz::Datensatz,
15 gemeinde::{GemeindeDaten, GemeindeSchluessel, RegionalSchluessel},
16 gemeindeverband::{GemeindeverbandDaten, GemeindeverbandSchluessel},
17 kreis::{KreisDaten, KreisSchluessel},
18 land::{LandDaten, LandSchluessel},
19 regierungsbezirk::{RegierungsbezirkDaten, RegierungsbezirkSchluessel},
20 region::{RegionDaten, RegionSchluessel},
21 },
22 parser::Parser,
23};
24
25#[derive(Clone, Debug, Default)]
27pub struct Database {
28 laender: BTreeMap<LandSchluessel, LandDaten>,
30
31 regierungsbezirke: BTreeMap<RegierungsbezirkSchluessel, RegierungsbezirkDaten>,
33
34 regionen: BTreeMap<RegionSchluessel, RegionDaten>,
36
37 kreise: BTreeMap<KreisSchluessel, KreisDaten>,
39
40 gemeindeverbaende: BTreeMap<GemeindeverbandSchluessel, GemeindeverbandDaten>,
42
43 gemeinden: BTreeMap<GemeindeSchluessel, GemeindeDaten>,
45
46 gemeindeverband_schluessel: HashMap<RegionalSchluessel, u16>,
47}
48
49impl Database {
50 pub fn from_reader<R: BufRead>(reader: R) -> Result<Self, Error> {
52 Self::from_parser(Parser::new(reader))
53 }
54
55 pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
57 Self::from_parser(Parser::from_path(path)?)
58 }
59
60 pub fn from_parser<R: BufRead>(mut parser: Parser<R>) -> Result<Self, Error> {
62 let mut db = Self::default();
63
64 while let Some(datensatz) = parser.parse_line()? {
65 db.insert(datensatz);
66 }
67
68 Ok(db)
69 }
70
71 pub fn insert(&mut self, datensatz: Datensatz) {
72 match datensatz {
73 Datensatz::Land(land) => {
74 self.laender.insert(land.schluessel, land);
75 }
76 Datensatz::Regierungsbezirk(regierungsbezirk) => {
77 self.regierungsbezirke
78 .insert(regierungsbezirk.schluessel, regierungsbezirk);
79 }
80 Datensatz::Region(region) => {
81 self.regionen.insert(region.schluessel, region);
82 }
83 Datensatz::Kreis(kreis) => {
84 self.kreise.insert(kreis.schluessel, kreis);
85 }
86 Datensatz::Gemeindeverband(gemeindeverband) => {
87 self.gemeindeverbaende
88 .insert(gemeindeverband.schluessel, gemeindeverband);
89 }
90 Datensatz::Gemeinde(gemeinde) => {
91 self.gemeindeverband_schluessel.insert(
92 gemeinde.schluessel.into(),
93 gemeinde.schluessel.gemeindeverband.gemeindeverband,
94 );
95 self.gemeinden.insert(gemeinde.schluessel.into(), gemeinde);
96 }
97 }
98 }
99
100 pub fn regional_to_gemeinde_schluessel(
101 &self,
102 regional_schluessel: RegionalSchluessel,
103 ) -> Option<GemeindeSchluessel> {
104 let gemeindeverband = self.gemeindeverband_schluessel.get(®ional_schluessel)?;
105 Some(regional_schluessel.to_gemeinde_schluessel(*gemeindeverband))
106 }
107
108 pub fn get<K, V>(&self, k: K) -> Option<&V>
109 where
110 V: Lookup<K>,
111 {
112 V::lookup(k, self)
113 }
114
115 pub fn all<'a, V>(&'a self) -> V::Iter
116 where
117 V: IterAll<'a>,
118 {
119 V::iter_all(self)
120 }
121
122 pub fn children<'a, K, V>(&'a self, k: K) -> impl Iterator<Item = &V>
123 where
124 V: IterChildrenOf<'a>,
125 K: IntoRangeKey<V::Key>,
126 {
127 V::iter_children_of(self, k).map(|(_, v)| v)
128 }
129}
130
131use std::ops::RangeInclusive;
132
133pub trait IntoRangeKey<T> {
136 fn into_range_key(self) -> RangeInclusive<T>;
137}
138
139impl IntoRangeKey<RegierungsbezirkSchluessel> for LandSchluessel {
141 fn into_range_key(self) -> RangeInclusive<RegierungsbezirkSchluessel> {
142 RegierungsbezirkSchluessel::new(self, u8::MIN)
143 ..=RegierungsbezirkSchluessel::new(self, u8::MAX)
144 }
145}
146
147impl IntoRangeKey<RegionSchluessel> for LandSchluessel {
149 fn into_range_key(self) -> RangeInclusive<RegionSchluessel> {
150 RegionSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MIN), u8::MIN)
151 ..=RegionSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MAX), u8::MAX)
152 }
153}
154
155impl IntoRangeKey<KreisSchluessel> for LandSchluessel {
157 fn into_range_key(self) -> RangeInclusive<KreisSchluessel> {
158 KreisSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MIN), u8::MIN)
159 ..=KreisSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MAX), u8::MAX)
160 }
161}
162
163impl IntoRangeKey<GemeindeverbandSchluessel> for LandSchluessel {
165 fn into_range_key(self) -> RangeInclusive<GemeindeverbandSchluessel> {
166 GemeindeverbandSchluessel::new(
167 KreisSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MIN), u8::MIN),
168 u16::MIN,
169 )
170 ..=GemeindeverbandSchluessel::new(
171 KreisSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MAX), u8::MAX),
172 u16::MAX,
173 )
174 }
175}
176
177impl IntoRangeKey<GemeindeSchluessel> for LandSchluessel {
179 fn into_range_key(self) -> RangeInclusive<GemeindeSchluessel> {
180 GemeindeSchluessel::new(
181 GemeindeverbandSchluessel::new(
182 KreisSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MIN), u8::MIN),
183 u16::MIN,
184 ),
185 u16::MIN,
186 )
187 ..=GemeindeSchluessel::new(
188 GemeindeverbandSchluessel::new(
189 KreisSchluessel::new(RegierungsbezirkSchluessel::new(self, u8::MAX), u8::MAX),
190 u16::MAX,
191 ),
192 u16::MAX,
193 )
194 }
195}
196
197impl IntoRangeKey<RegionSchluessel> for RegierungsbezirkSchluessel {
199 fn into_range_key(self) -> RangeInclusive<RegionSchluessel> {
200 RegionSchluessel::new(self, u8::MIN)..=RegionSchluessel::new(self, u8::MAX)
201 }
202}
203
204impl IntoRangeKey<KreisSchluessel> for RegierungsbezirkSchluessel {
206 fn into_range_key(self) -> RangeInclusive<KreisSchluessel> {
207 KreisSchluessel::new(self, u8::MIN)..=KreisSchluessel::new(self, u8::MAX)
208 }
209}
210
211impl IntoRangeKey<GemeindeverbandSchluessel> for RegierungsbezirkSchluessel {
214 fn into_range_key(self) -> RangeInclusive<GemeindeverbandSchluessel> {
215 GemeindeverbandSchluessel::new(KreisSchluessel::new(self, u8::MIN), u16::MIN)
216 ..=GemeindeverbandSchluessel::new(KreisSchluessel::new(self, u8::MAX), u16::MAX)
217 }
218}
219
220impl IntoRangeKey<GemeindeSchluessel> for RegierungsbezirkSchluessel {
222 fn into_range_key(self) -> RangeInclusive<GemeindeSchluessel> {
223 GemeindeSchluessel::new(
224 GemeindeverbandSchluessel::new(KreisSchluessel::new(self, u8::MIN), u16::MIN),
225 u16::MIN,
226 )
227 ..=GemeindeSchluessel::new(
228 GemeindeverbandSchluessel::new(KreisSchluessel::new(self, u8::MAX), u16::MAX),
229 u16::MAX,
230 )
231 }
232}
233
234impl IntoRangeKey<GemeindeverbandSchluessel> for KreisSchluessel {
236 fn into_range_key(self) -> RangeInclusive<GemeindeverbandSchluessel> {
237 GemeindeverbandSchluessel::new(self, u16::MIN)
238 ..=GemeindeverbandSchluessel::new(self, u16::MAX)
239 }
240}
241
242impl IntoRangeKey<GemeindeSchluessel> for KreisSchluessel {
244 fn into_range_key(self) -> RangeInclusive<GemeindeSchluessel> {
245 GemeindeSchluessel::new(GemeindeverbandSchluessel::new(self, u16::MIN), u16::MIN)
246 ..=GemeindeSchluessel::new(GemeindeverbandSchluessel::new(self, u16::MAX), u16::MAX)
247 }
248}
249
250impl IntoRangeKey<GemeindeSchluessel> for GemeindeverbandSchluessel {
252 fn into_range_key(self) -> RangeInclusive<GemeindeSchluessel> {
253 GemeindeSchluessel::new(self, u16::MIN)..=GemeindeSchluessel::new(self, u16::MAX)
254 }
255}
256
257pub trait Lookup<K> {
258 fn lookup<'a>(key: K, db: &'a Database) -> Option<&'a Self>;
259}
260
261impl Lookup<LandSchluessel> for LandDaten {
262 fn lookup<'a>(key: LandSchluessel, db: &'a Database) -> Option<&'a Self> {
263 db.laender.get(&key)
264 }
265}
266
267impl Lookup<RegierungsbezirkSchluessel> for LandDaten {
268 fn lookup<'a>(key: RegierungsbezirkSchluessel, db: &'a Database) -> Option<&'a Self> {
269 db.laender.get(&key.into())
270 }
271}
272
273impl Lookup<RegionSchluessel> for LandDaten {
274 fn lookup<'a>(key: RegionSchluessel, db: &'a Database) -> Option<&'a Self> {
275 db.laender.get(&key.into())
276 }
277}
278
279impl Lookup<KreisSchluessel> for LandDaten {
280 fn lookup<'a>(key: KreisSchluessel, db: &'a Database) -> Option<&'a Self> {
281 db.laender.get(&key.into())
282 }
283}
284
285impl Lookup<GemeindeverbandSchluessel> for LandDaten {
286 fn lookup<'a>(key: GemeindeverbandSchluessel, db: &'a Database) -> Option<&'a Self> {
287 db.laender.get(&key.into())
288 }
289}
290
291impl Lookup<GemeindeSchluessel> for LandDaten {
292 fn lookup<'a>(key: GemeindeSchluessel, db: &'a Database) -> Option<&'a Self> {
293 db.laender.get(&key.into())
294 }
295}
296
297impl Lookup<RegierungsbezirkSchluessel> for RegierungsbezirkDaten {
298 fn lookup<'a>(key: RegierungsbezirkSchluessel, db: &'a Database) -> Option<&'a Self> {
299 db.regierungsbezirke.get(&key)
300 }
301}
302
303impl Lookup<RegionSchluessel> for RegierungsbezirkDaten {
304 fn lookup<'a>(key: RegionSchluessel, db: &'a Database) -> Option<&'a Self> {
305 db.regierungsbezirke.get(&key.into())
306 }
307}
308
309impl Lookup<KreisSchluessel> for RegierungsbezirkDaten {
310 fn lookup<'a>(key: KreisSchluessel, db: &'a Database) -> Option<&'a Self> {
311 db.regierungsbezirke.get(&key.into())
312 }
313}
314
315impl Lookup<GemeindeverbandSchluessel> for RegierungsbezirkDaten {
316 fn lookup<'a>(key: GemeindeverbandSchluessel, db: &'a Database) -> Option<&'a Self> {
317 db.regierungsbezirke.get(&key.into())
318 }
319}
320
321impl Lookup<GemeindeSchluessel> for RegierungsbezirkDaten {
322 fn lookup<'a>(key: GemeindeSchluessel, db: &'a Database) -> Option<&'a Self> {
323 db.regierungsbezirke.get(&key.into())
324 }
325}
326
327impl Lookup<RegionSchluessel> for RegionDaten {
328 fn lookup<'a>(key: RegionSchluessel, db: &'a Database) -> Option<&'a Self> {
329 db.regionen.get(&key)
330 }
331}
332
333impl Lookup<KreisSchluessel> for KreisDaten {
334 fn lookup<'a>(key: KreisSchluessel, db: &'a Database) -> Option<&'a Self> {
335 db.kreise.get(&key)
336 }
337}
338
339impl Lookup<GemeindeverbandSchluessel> for KreisDaten {
340 fn lookup<'a>(key: GemeindeverbandSchluessel, db: &'a Database) -> Option<&'a Self> {
341 db.kreise.get(&key.into())
342 }
343}
344
345impl Lookup<GemeindeSchluessel> for KreisDaten {
346 fn lookup<'a>(key: GemeindeSchluessel, db: &'a Database) -> Option<&'a Self> {
347 db.kreise.get(&key.into())
348 }
349}
350
351impl Lookup<GemeindeverbandSchluessel> for GemeindeverbandDaten {
352 fn lookup<'a>(key: GemeindeverbandSchluessel, db: &'a Database) -> Option<&'a Self> {
353 db.gemeindeverbaende.get(&key)
354 }
355}
356
357impl Lookup<GemeindeSchluessel> for GemeindeverbandDaten {
358 fn lookup<'a>(key: GemeindeSchluessel, db: &'a Database) -> Option<&'a Self> {
359 db.gemeindeverbaende.get(&key.into())
360 }
361}
362
363impl Lookup<GemeindeSchluessel> for GemeindeDaten {
364 fn lookup<'a>(key: GemeindeSchluessel, db: &'a Database) -> Option<&'a Self> {
365 db.gemeinden.get(&key)
366 }
367}
368
369impl Lookup<RegionalSchluessel> for GemeindeDaten {
370 fn lookup<'a>(key: RegionalSchluessel, db: &'a Database) -> Option<&'a Self> {
371 let key = db.regional_to_gemeinde_schluessel(key)?;
372 db.gemeinden.get(&key)
373 }
374}
375
376pub trait IterAll<'a>: 'a {
378 type Iter: Iterator<Item = &'a Self> + 'a;
379
380 fn iter_all(db: &'a Database) -> Self::Iter;
381}
382
383impl<'a> IterAll<'a> for LandDaten {
384 type Iter = btree_map::Values<'a, LandSchluessel, LandDaten>;
385
386 fn iter_all(db: &'a Database) -> Self::Iter {
387 db.laender.values()
388 }
389}
390
391impl<'a> IterAll<'a> for RegierungsbezirkDaten {
392 type Iter = btree_map::Values<'a, RegierungsbezirkSchluessel, RegierungsbezirkDaten>;
393
394 fn iter_all(db: &'a Database) -> Self::Iter {
395 db.regierungsbezirke.values()
396 }
397}
398
399impl<'a> IterAll<'a> for RegionDaten {
400 type Iter = btree_map::Values<'a, RegionSchluessel, RegionDaten>;
401
402 fn iter_all(db: &'a Database) -> Self::Iter {
403 db.regionen.values()
404 }
405}
406
407impl<'a> IterAll<'a> for KreisDaten {
408 type Iter = btree_map::Values<'a, KreisSchluessel, KreisDaten>;
409
410 fn iter_all(db: &'a Database) -> Self::Iter {
411 db.kreise.values()
412 }
413}
414
415impl<'a> IterAll<'a> for GemeindeverbandDaten {
416 type Iter = btree_map::Values<'a, GemeindeverbandSchluessel, GemeindeverbandDaten>;
417
418 fn iter_all(db: &'a Database) -> Self::Iter {
419 db.gemeindeverbaende.values()
420 }
421}
422
423impl<'a> IterAll<'a> for GemeindeDaten {
424 type Iter = btree_map::Values<'a, GemeindeSchluessel, GemeindeDaten>;
425
426 fn iter_all(db: &'a Database) -> Self::Iter {
427 db.gemeinden.values()
428 }
429}
430
431pub trait IterChildrenOf<'a>: 'a {
433 type Iter: Iterator<Item = (&'a Self::Key, &'a Self)>;
434 type Key;
435
436 fn iter_children_of<K: IntoRangeKey<Self::Key>>(db: &'a Database, key: K) -> Self::Iter;
437}
438
439impl<'a> IterChildrenOf<'a> for RegierungsbezirkDaten {
440 type Iter = btree_map::Range<'a, Self::Key, Self>;
441 type Key = RegierungsbezirkSchluessel;
442
443 fn iter_children_of<K: IntoRangeKey<Self::Key>>(db: &'a Database, key: K) -> Self::Iter {
444 db.regierungsbezirke.range(key.into_range_key())
445 }
446}
447
448impl<'a> IterChildrenOf<'a> for RegionDaten {
449 type Iter = btree_map::Range<'a, Self::Key, Self>;
450 type Key = RegionSchluessel;
451
452 fn iter_children_of<K: IntoRangeKey<Self::Key>>(db: &'a Database, key: K) -> Self::Iter {
453 db.regionen.range(key.into_range_key())
454 }
455}
456
457impl<'a> IterChildrenOf<'a> for KreisDaten {
458 type Iter = btree_map::Range<'a, Self::Key, Self>;
459 type Key = KreisSchluessel;
460
461 fn iter_children_of<K: IntoRangeKey<Self::Key>>(db: &'a Database, key: K) -> Self::Iter {
462 db.kreise.range(key.into_range_key())
463 }
464}
465
466impl<'a> IterChildrenOf<'a> for GemeindeverbandDaten {
467 type Iter = btree_map::Range<'a, Self::Key, Self>;
468 type Key = GemeindeverbandSchluessel;
469
470 fn iter_children_of<K: IntoRangeKey<Self::Key>>(db: &'a Database, key: K) -> Self::Iter {
471 db.gemeindeverbaende.range(key.into_range_key())
472 }
473}
474
475impl<'a> IterChildrenOf<'a> for GemeindeDaten {
476 type Iter = btree_map::Range<'a, Self::Key, Self>;
477 type Key = GemeindeSchluessel;
478
479 fn iter_children_of<K: IntoRangeKey<Self::Key>>(db: &'a Database, key: K) -> Self::Iter {
480 db.gemeinden.range(key.into_range_key())
481 }
482}
483
484#[cfg(test)]
485mod tests {
486 use std::io::Cursor;
487
488 use crate::model::{
489 gemeinde::GemeindeDaten,
490 kreis::{KreisDaten, KreisSchluessel},
491 land::{LandDaten, LandSchluessel},
492 };
493
494 use super::*;
495
496 fn load_testset() -> Database {
497 let data = r#"102021043010 Saarland Saarbrücken, Landeshauptstadt
498402021043010041 Regionalverband Saarbrücken Saarbrücken, Landeshauptstadt 45
499502021043010041 0100Saarbrücken, Landeshauptstadt 50
500502021043010041 0511Friedrichsthal, Stadt 50
5016020210430100411000100Saarbrücken, Landeshauptstadt 63 000000167520000018037400000089528 66111***** 1040110955501296
5026020210430100415110511Friedrichsthal, Stadt 63 000000008990000000998700000004907 66299 1070110955513299
503402021043010042 Merzig-Wadern Merzig, Kreisstadt 44
504502021043010042 0111Beckingen 50
505502021043010042 0112Losheim am See 50
5066020210430100421110111Beckingen 64 000000051850000001488900000007315 66701 1020110455523297
5076020210430100421120112Losheim am See 64 000000096950000001603800000007974 66679 1020110455525297
508102021043011 Berlin Berlin "#;
509
510 Database::from_reader(Cursor::new(data)).unwrap()
511 }
512
513 #[test]
514 fn get_land_from_landschluessel() {
515 let db = load_testset();
516 let land: &LandDaten = db.get(LandSchluessel::new(10)).unwrap();
517 assert_eq!(land.name, "Saarland");
518 }
519
520 #[test]
521 fn get_land_from_kreisschluessel() {
522 let db = load_testset();
523 let land: &LandDaten = db
524 .get(KreisSchluessel::new_land(LandSchluessel::new(10), 100))
525 .unwrap();
526 assert_eq!(land.name, "Saarland");
527 }
528
529 #[test]
530 fn get_land_from_gemeindeschluessel() {
531 let db = load_testset();
532 let land: &LandDaten = db
533 .get("100420111111".parse::<GemeindeSchluessel>().unwrap())
534 .unwrap();
535 assert_eq!(land.name, "Saarland");
536 }
537
538 #[test]
539 fn get_gemeinde() {
540 let db = load_testset();
541 let gemeinde: &GemeindeDaten = db
542 .get("100420111111".parse::<GemeindeSchluessel>().unwrap())
543 .unwrap();
544 assert_eq!(gemeinde.name, "Beckingen");
545 }
546
547 #[test]
548 fn get_gemeinde_from_regional_schluessel() {
549 let db = load_testset();
550 let gemeinde: &GemeindeDaten = db
551 .get("10042111".parse::<RegionalSchluessel>().unwrap())
552 .unwrap();
553 assert_eq!(gemeinde.name, "Beckingen");
554 }
555
556 #[test]
557 fn iter_all_laender() {
558 let db = load_testset();
559 let laender = db.all::<LandDaten>().collect::<Vec<_>>();
560
561 assert_eq!(laender.len(), 2);
562 assert_eq!(laender[0].name, "Saarland");
563 assert_eq!(laender[1].name, "Berlin");
564 }
565
566 #[test]
567 fn iter_all_kreise() {
568 let db = load_testset();
569 let kreise = db.all::<KreisDaten>().collect::<Vec<_>>();
570
571 assert_eq!(kreise.len(), 2);
572 assert_eq!(kreise[0].name, "Regionalverband Saarbrücken");
573 assert_eq!(kreise[1].name, "Merzig-Wadern");
574 }
575
576 #[test]
577 fn iter_all_gemeinden() {
578 let db = load_testset();
579 let gemeinden = db.all::<GemeindeDaten>().collect::<Vec<_>>();
580
581 assert_eq!(gemeinden.len(), 4);
582 assert_eq!(gemeinden[0].name, "Saarbrücken, Landeshauptstadt");
583 assert_eq!(gemeinden[1].name, "Friedrichsthal, Stadt");
584 assert_eq!(gemeinden[2].name, "Beckingen");
585 assert_eq!(gemeinden[3].name, "Losheim am See");
586 }
587
588 #[test]
589 fn iter_gemeinden_in_kreis() {
590 let db = load_testset();
591 let gemeinden = db
592 .children::<_, GemeindeDaten>(KreisSchluessel::new_land(LandSchluessel::new(10), 41))
593 .collect::<Vec<_>>();
594
595 assert_eq!(gemeinden.len(), 2);
596 assert_eq!(gemeinden[0].name, "Saarbrücken, Landeshauptstadt");
597 assert_eq!(gemeinden[1].name, "Friedrichsthal, Stadt");
598 }
599}