#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum Error { BadWidth { expected: usize, got: usize }, } /// A two-dimensional grid of values. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Grid { width: usize, height: usize, rows: Vec>, } impl Grid { /// Creates a new grid with a given `width` and `height`. The data is given as a [`Vec`] of /// rows, each row a [`Vec`] of values. /// /// # Errors /// /// Returns an error if the given data does not match up with the dimensions. pub fn from_rows(rows: Vec>) -> Result { let row_len = rows.get(0).map_or(0, Vec::len); if let Some(err) = rows.iter().map(Vec::len).find_map(|l| { (l != row_len).then_some(Error::BadWidth { expected: row_len, got: l, }) }) { return Err(err); } Ok(Self { width: rows.get(0).map_or(0, std::vec::Vec::len), height: rows.len(), rows, }) } pub fn rows(&self) -> impl Iterator> { self.rows.iter().map(|row| row.iter()) } pub fn cols(&self) -> impl Iterator> { (0..self.width).map(|i| self.rows.iter().map(move |r| &r[i])) } pub fn rows_mut(&mut self) -> impl Iterator> { self.rows.iter_mut().map(|row| row.iter_mut()) } /* pub fn cols_mut(&mut self) -> impl Iterator> { (0..self.width).map(move |i| { self.rows.iter_mut().map(move |r| { let i: usize = i; let x: &mut T = &mut r[i]; x }) }) } */ }