use crate::{
core::Pos,
grid::{BoundedGrid, GridBase},
};
pub trait GridRead: GridBase {
fn get(&self, pos: Pos) -> Option<&Self::Element>;
}
pub trait GridReadUnchecked: GridBase {
unsafe fn get_unchecked(&self, pos: Pos) -> &Self::Element;
}
impl<T: GridReadUnchecked + BoundedGrid> GridRead for T {
fn get(&self, pos: Pos) -> Option<&Self::Element> {
if self.contains_pos(pos) {
Some(unsafe { self.get_unchecked(pos) })
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
struct TestGrid {
grid: [[u8; 3]; 3],
}
impl GridBase for TestGrid {
type Element = u8;
}
unsafe impl BoundedGrid for TestGrid {
fn width(&self) -> usize {
3
}
fn height(&self) -> usize {
3
}
}
impl GridReadUnchecked for TestGrid {
unsafe fn get_unchecked(&self, pos: Pos) -> &Self::Element {
&self.grid[pos.y][pos.x]
}
}
#[test]
fn test_get_ok() {
let grid = TestGrid {
grid: [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
};
assert_eq!(grid.get(Pos::new(1, 1)), Some(&5));
}
#[test]
fn test_get_out_of_bounds_x() {
let grid = TestGrid {
grid: [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
};
assert_eq!(grid.get(Pos::new(3, 1)), None);
}
#[test]
fn test_get_out_of_bounds_y() {
let grid = TestGrid {
grid: [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
};
assert_eq!(grid.get(Pos::new(1, 3)), None);
}
}