use std::error::Error; use std::fmt; use std::str::FromStr; #[derive(Debug, Eq, PartialEq)] pub struct Position { pub x: u8, pub y: u8, } impl Error for Position {} impl FromStr for Position { type Err = String; fn from_str(s: &str) -> Result { let mut parts = s.split(','); let x = parts.next().unwrap().parse(); let y = parts.next().unwrap().parse(); if x.is_err() { Err("bad x supplied for position".to_string()) } else if y.is_err() { Err("bad y supplied for position".to_string()) } else { let x = x.unwrap(); let y = y.unwrap(); Ok(Position { x, y }) } } } impl fmt::Display for Position { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{},{}", self.x, self.y) } } #[cfg(test)] mod test { use crate::position::Position; use std::str::FromStr; #[test] fn test_position_from_str() { assert_eq!( Position::from_str(&"4,12").unwrap(), Position { x: 4, y: 12 } ); } #[test] fn test_position_to_string() { assert_eq!(Position { x: 4, y: 12 }.to_string(), "4,12".to_string()) } }