From d0b70749b55206145045ee5dd3f854947a397c6b Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sun, 3 Dec 2023 08:06:05 +0000 Subject: [PATCH] common/rust: add Grid type --- common/rust/src/grid.rs | 62 +++++++++++++++++++++++++++++++++++++++++ common/rust/src/lib.rs | 1 + 2 files changed, 63 insertions(+) create mode 100644 common/rust/src/grid.rs diff --git a/common/rust/src/grid.rs b/common/rust/src/grid.rs new file mode 100644 index 0000000..2f9d1a0 --- /dev/null +++ b/common/rust/src/grid.rs @@ -0,0 +1,62 @@ +#[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. + #[must_use] + pub fn from_rows(rows: Vec>) -> Result { + rows.iter().map(Vec::len).try_reduce(|l1, l2| { + if l2 != l1 { + Err(Error::BadWidth { + expected: l1, + got: l2, + }) + } else { + Ok(l2) + } + })?; + + Ok(Self { + width: rows.get(0).map_or(0, |r| r.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 + }) + }) + } +} diff --git a/common/rust/src/lib.rs b/common/rust/src/lib.rs index aa9633a..46e1dde 100644 --- a/common/rust/src/lib.rs +++ b/common/rust/src/lib.rs @@ -3,6 +3,7 @@ mod section_range; pub mod vec2; pub mod vecn; +pub mod grid; use std::{mem, path::Path};