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