use crate::errors::MapParseError; use std::convert::TryFrom; pub struct Map { width: usize, _height: usize, data: Vec>, } impl<'a, E, X> TryFrom<&'a str> for Map where X: Clone + TryFrom, E: From, { type Error = E; fn try_from(s: &str) -> Result, E> { let mut width = 0; let mut _height = 0; let mut data = Vec::new(); for line in s.lines() { let mut current_line = Vec::with_capacity(width); for char in line.chars() { let item = X::try_from(char)?; current_line.push(item); } _height += 1; if width == 0 { width = current_line.len(); } else if width != current_line.len() { return Err(E::from(MapParseError::UnevenLines(_height))); } data.push(current_line); } Ok(Map { width, _height, data, }) } } impl Map { pub fn at(&self, x: usize, y: usize) -> Option { let row = self.data.get(y)?; let wrapped_x = x % self.width; Some(row[wrapped_x].clone()) } }