1use crate::id::{define_id_getter, define_id_type, IDCollection};
3use anyhow::{ensure, Result};
4use indexmap::IndexMap;
5use serde::Deserialize;
6use std::collections::HashSet;
7
8define_id_type! {RegionID}
9
10pub type RegionMap = IndexMap<RegionID, Region>;
12
13#[derive(Debug, Deserialize, PartialEq)]
15pub struct Region {
16 pub id: RegionID,
18 pub description: String,
20}
21define_id_getter! {Region, RegionID}
22
23pub fn parse_region_str(s: &str, region_ids: &HashSet<RegionID>) -> Result<HashSet<RegionID>> {
28 let s = s.trim();
29 ensure!(!s.is_empty(), "No regions provided");
30
31 if s.eq_ignore_ascii_case("all") {
32 return Ok(region_ids.clone());
33 }
34
35 s.split(";")
36 .map(|y| region_ids.get_id_by_str(y.trim()))
37 .collect()
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn test_parse_region_str() {
46 let region_ids: HashSet<RegionID> = ["GBR".into(), "USA".into()].into_iter().collect();
47
48 let parsed = parse_region_str("GBR;USA", ®ion_ids).unwrap();
50 assert_eq!(parsed.len(), 2);
51 assert!(parsed.contains(&RegionID::from("GBR")));
52 assert!(parsed.contains(&RegionID::from("USA")));
53
54 let parsed = parse_region_str("all", ®ion_ids).unwrap();
56 assert_eq!(parsed.len(), 2);
57 assert!(parsed.contains(&RegionID::from("GBR")));
58 assert!(parsed.contains(&RegionID::from("USA")));
59
60 let parsed = parse_region_str("GBR", ®ion_ids).unwrap();
62 assert_eq!(parsed.len(), 1);
63 assert!(parsed.contains(&RegionID::from("GBR")));
64
65 let result = parse_region_str("", ®ion_ids);
67 assert!(result.is_err());
68
69 let result = parse_region_str("GBR;INVALID", ®ion_ids);
71 assert!(result.is_err());
72 }
73}