use regex::Regex; use std::convert::TryFrom; use std::num::ParseIntError; use thiserror::Error; #[derive(Debug, Clone, Error)] pub enum RegionParseError { #[error("Regex Error '{0}'")] RegexError(#[from] regex::Error), #[error("Int parse error '{0}'")] IntParseError(#[from] ParseIntError), #[error("Cannot parse region file name '{0}'")] RegionNameParseFailure(String), } /// Struct to store information about the region pub struct Region { /// x position of the region pub x: i64, /// y position of the region pub y: i64, } impl TryFrom for Region { type Error = RegionParseError; /// Try from string fn try_from(value: String) -> Result { let re = Regex::new(r"r\.(?P-?[0-9]*)+\.(?P-?[0-9]*)")?; if re.is_match(&value) { let captures = re.captures(value.as_str()).unwrap(); return Ok(Region { x: captures["x"].parse::()?, y: captures["y"].parse::()?, }); } Err(RegionParseError::RegionNameParseFailure(value)) } } #[cfg(test)] mod test { use crate::region::Region; #[test] fn test_parse_success() { let region_x = 5; let region_y = -15; let region_string = format!("r.{region_x}.{region_y}"); let region = Region::try_from(region_string).unwrap(); assert_eq!(region.x, region_x); assert_eq!(region.y, region_y); } #[test] fn test_parse_failure() { let region_y = -15; let region_string = format!("r.pb.{region_y}"); assert!(Region::try_from(region_string).is_err()); } }