common/rust: add Grid type
This commit is contained in:
parent
e2433598c3
commit
d0b70749b5
2 changed files with 63 additions and 0 deletions
62
common/rust/src/grid.rs
Normal file
62
common/rust/src/grid.rs
Normal 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
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
mod section_range;
|
mod section_range;
|
||||||
pub mod vec2;
|
pub mod vec2;
|
||||||
pub mod vecn;
|
pub mod vecn;
|
||||||
|
pub mod grid;
|
||||||
|
|
||||||
use std::{mem, path::Path};
|
use std::{mem, path::Path};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue