common/rust: add Grid type

This commit is contained in:
Xiretza 2023-12-03 08:06:05 +00:00
parent e2433598c3
commit d0b70749b5
2 changed files with 63 additions and 0 deletions

62
common/rust/src/grid.rs Normal file
View file

@ -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<T> {
width: usize,
height: usize,
rows: Vec<Vec<T>>,
}
impl<T> Grid<T> {
/// 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<Vec<T>>) -> Result<Self, Error> {
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<Item = impl Iterator<Item = &T>> {
self.rows.iter().map(|row| row.iter())
}
pub fn cols(&self) -> impl Iterator<Item = impl Iterator<Item = &T>> {
(0..self.width).map(|i| self.rows.iter().map(move |r| &r[i]))
}
pub fn rows_mut(&mut self) -> impl Iterator<Item = impl Iterator<Item = &mut T>> {
self.rows.iter_mut().map(|row| row.iter_mut())
}
pub fn cols_mut(&mut self) -> impl Iterator<Item = impl Iterator<Item = &mut T>> {
(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
})
})
}
}

View file

@ -3,6 +3,7 @@
mod section_range;
pub mod vec2;
pub mod vecn;
pub mod grid;
use std::{mem, path::Path};