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}