cell_grid/legacy/
mod.rs

1#![allow(deprecated)]
2
3mod coord;
4mod rect;
5
6use alloc::vec::Vec;
7
8pub use coord::Coord;
9pub use rect::Rect;
10
11/// A 2d fixed-size grid containers for cells of type `T`
12#[deprecated(since = "0.1.4", note = "Use `DynamicGrid` instead")]
13#[derive(Debug, Clone, Eq, PartialEq)]
14pub struct Grid<T> {
15    cells: Vec<T>,
16    width: usize,
17}
18
19impl<T: Default> Grid<T> {
20    /// Create a grid using the default value of `T` for each cell
21    ///
22    /// # Example
23    ///
24    /// ```
25    /// # use cell_grid::{Grid, Coord};
26    /// let grid: Grid<i32> = Grid::new(2, 2);
27    /// assert_eq!(grid.get([0, 0]), Some(&0));
28    /// assert_eq!(grid.get([1, 0]), Some(&0));
29    /// assert_eq!(grid.get([0, 1]), Some(&0));
30    /// assert_eq!(grid.get([1, 1]), Some(&0));
31    /// ```
32    #[must_use]
33    pub fn new(width: usize, height: usize) -> Self {
34        Self::new_with(width, height, |_| T::default())
35    }
36}
37
38impl<T> Grid<T> {
39    /// Create a grid using `init_cell` function for each cell
40    ///
41    /// # Example
42    ///
43    /// ```
44    /// # use cell_grid::{Grid, Coord};
45    /// let grid = Grid::new_with(2, 2, |coord| coord);
46    /// assert_eq!(grid.get([0, 0]), Some(&Coord { x: 0, y: 0 }));
47    /// assert_eq!(grid.get([1, 0]), Some(&Coord { x: 1, y: 0 }));
48    /// assert_eq!(grid.get([0, 1]), Some(&Coord { x: 0, y: 1 }));
49    /// assert_eq!(grid.get([1, 1]), Some(&Coord { x: 1, y: 1 }));
50    /// ```
51    #[must_use]
52    pub fn new_with(width: usize, height: usize, init_cell: impl FnMut(Coord) -> T) -> Self {
53        Self::from_row_major_iter(
54            width,
55            (0..(width * height))
56                .map(|i| Coord::from_index(width, i))
57                .map(init_cell),
58        )
59    }
60
61    /// Create a grid using the row-major `iter`
62    ///
63    /// # Example
64    ///
65    /// ```
66    /// # use cell_grid::Grid;
67    /// let grid = Grid::from_row_major_iter(2, [1, 2, 3, 4]);
68    /// assert_eq!(grid.get([0, 0]), Some(&1));
69    /// assert_eq!(grid.get([1, 0]), Some(&2));
70    /// assert_eq!(grid.get([0, 1]), Some(&3));
71    /// assert_eq!(grid.get([1, 1]), Some(&4));
72    /// ```
73    #[must_use]
74    pub fn from_row_major_iter(width: usize, iter: impl IntoIterator<Item = T>) -> Self {
75        let cells = iter.into_iter().collect();
76        Self { cells, width }
77    }
78
79    /// Access the cell at `coord`
80    ///
81    /// Returns `None` if the `coord` is out of bounds
82    #[must_use]
83    pub fn get(&self, coord: impl Into<Coord>) -> Option<&T> {
84        let index = coord.into().into_index(self.width)?;
85        self.cells.get(index)
86    }
87
88    /// Access mutably the cell at `coord`
89    ///
90    /// Returns `None` if the `coord` is out of bounds
91    pub fn get_mut(&mut self, coord: impl Into<Coord>) -> Option<&mut T> {
92        let index = coord.into().into_index(self.width)?;
93        self.cells.get_mut(index)
94    }
95
96    /// Set the value of the cell at `coord`
97    ///
98    /// # Panics
99    ///
100    /// Panics if the `coord` is out-of-bounds
101    ///
102    /// For a non-panicking version, use `get_mut`
103    pub fn set(&mut self, coord: impl Into<Coord>, value: T) {
104        let cell = self.get_mut(coord).expect("coordinate is out-of-bounds");
105        *cell = value;
106    }
107
108    /// Iterator over all cells
109    pub fn cells(&self) -> impl Iterator<Item = &T> {
110        self.cells.iter()
111    }
112
113    /// Iterator over cells in `rect`
114    pub fn cells_in_rect(&self, rect: impl Into<Rect>) -> impl Iterator<Item = &T> {
115        rect.into().coords().filter_map(|c| self.get(c))
116    }
117}