swamp_script_core_extra/
grid.rs

1pub struct ColumnIter<'a, T> {
2    grid: &'a Grid<T>,
3    x: usize,
4    y: usize,
5}
6
7impl<'a, T> Iterator for ColumnIter<'a, T> {
8    type Item = &'a T;
9
10    fn next(&mut self) -> Option<Self::Item> {
11        if self.y < self.grid.height {
12            let item = &self.grid.data[self.y * self.grid.width + self.x];
13            self.y += 1;
14            Some(item)
15        } else {
16            None
17        }
18    }
19}
20
21#[derive(Debug, Clone)]
22pub struct Grid<T> {
23    width: usize,
24    height: usize,
25    pub data: Vec<T>,
26}
27
28impl<T: Clone> Grid<T> {
29    pub fn new(width: usize, height: usize, initial: T) -> Self {
30        Self {
31            width,
32            height,
33            data: vec![initial; width * height],
34        }
35    }
36
37    pub fn column(&self, x: usize) -> Option<Vec<T>> {
38        if x < self.width {
39            Some(
40                (0..self.height)
41                    .map(|y| self.data[y * self.width + x].clone())
42                    .collect(),
43            )
44        } else {
45            None
46        }
47    }
48}
49
50impl<T> Grid<T> {
51    #[must_use]
52    pub fn get(&self, x: usize, y: usize) -> Option<&T> {
53        if y < self.height && x < self.width {
54            Some(&self.data[y * self.width + x])
55        } else {
56            None
57        }
58    }
59
60    #[must_use]
61    pub fn get_mut(&mut self, x: usize, y: usize) -> Option<&mut T> {
62        if y < self.height && x < self.width {
63            Some(&mut self.data[y * self.width + x])
64        } else {
65            None
66        }
67    }
68
69    pub fn set(&mut self, x: usize, y: usize, data: T) -> Option<()> {
70        if x < self.width && y < self.height {
71            self.data[y * self.width + x] = data;
72            Some(())
73        } else {
74            None
75        }
76    }
77
78    pub fn rows(&self) -> impl Iterator<Item = &[T]> {
79        self.data.chunks(self.width)
80    }
81
82    pub fn columns(&self) -> impl Iterator<Item = ColumnIter<'_, T>> {
83        (0..self.width).map(move |x| ColumnIter {
84            grid: self,
85            x,
86            y: 0,
87        })
88    }
89}