use regex::Regex; use std::error::Error; use std::fmt; use std::num::ParseIntError; use std::str::FromStr; /// Chunk error #[derive(Debug)] pub enum ChunkCoordinateErr { /// Error parsing integer ParseIntError(ParseIntError), /// Regex error RegexError(regex::Error), /// Invalid chunk coordinate given InvalidChunk, } impl From for ChunkCoordinateErr { fn from(e: ParseIntError) -> Self { Self::ParseIntError(e) } } impl From for ChunkCoordinateErr { fn from(e: regex::Error) -> Self { Self::RegexError(e) } } impl fmt::Display for ChunkCoordinateErr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Unable to parse chunk range: {:?}", self) } } impl Error for ChunkCoordinateErr {} /// Chunk Coordinate paiir #[derive(Debug)] pub struct ChunkCoordinate { /// X Coordinate pub x: i32, /// Z Coordinate pub z: i32, } impl FromStr for ChunkCoordinate { type Err = ChunkCoordinateErr; fn from_str(s: &str) -> Result { let re = Regex::new(r"\((?P-?[0-9]*),(?P-?[0-9]*)\)").unwrap(); if let Some(cap) = re.captures(s) { let x = cap["x"].parse::()?; let z = cap["z"].parse::()?; Ok(Self { x, z }) } else { Err(ChunkCoordinateErr::InvalidChunk) } } }