use crate::id::{IDCollection, define_id_getter, define_id_type};
use anyhow::{Result, ensure};
use indexmap::{IndexMap, IndexSet};
use serde::Deserialize;
define_id_type! {RegionID}
pub type RegionMap = IndexMap<RegionID, Region>;
#[derive(Debug, Deserialize, PartialEq)]
pub struct Region {
pub id: RegionID,
pub description: String,
}
define_id_getter! {Region, RegionID}
pub fn parse_region_str(s: &str, region_ids: &IndexSet<RegionID>) -> Result<IndexSet<RegionID>> {
let s = s.trim();
ensure!(!s.is_empty(), "No regions provided");
if s.eq_ignore_ascii_case("all") {
return Ok(region_ids.clone());
}
s.split(';')
.map(|y| Ok(region_ids.get_id(y.trim())?.clone()))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_region_str_works() {
let region_ids: IndexSet<RegionID> = ["GBR".into(), "USA".into()].into_iter().collect();
let parsed = parse_region_str("GBR;USA", ®ion_ids).unwrap();
assert_eq!(parsed.len(), 2);
assert!(parsed.contains(&RegionID::from("GBR")));
assert!(parsed.contains(&RegionID::from("USA")));
let parsed = parse_region_str("all", ®ion_ids).unwrap();
assert_eq!(parsed.len(), 2);
assert!(parsed.contains(&RegionID::from("GBR")));
assert!(parsed.contains(&RegionID::from("USA")));
let parsed = parse_region_str("GBR", ®ion_ids).unwrap();
assert_eq!(parsed.len(), 1);
assert!(parsed.contains(&RegionID::from("GBR")));
let result = parse_region_str("", ®ion_ids);
result.unwrap_err();
let result = parse_region_str("GBR;INVALID", ®ion_ids);
result.unwrap_err();
}
}