From 90d2e1636a198d4e7958912f0a677d1bd9dded93 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..3f893e4 --- /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. + 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 + }) + }) + } + */ +} 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};