Skip to main content

grid_map/dim/
dim_locs.rs

1use crate::{Dim, Loc};
2
3impl Dim {
4    //! Iteration
5
6    /// Returns an iterator over all locations in the dimensions
7    pub fn locs(self) -> DimLocs {
8        DimLocs::from(self)
9    }
10}
11
12/// An iterator over all `Loc`s in a `Dim`.
13#[derive(Clone, Debug)]
14pub struct DimLocs {
15    dims: Dim,
16    current: Loc,
17}
18
19impl From<Dim> for DimLocs {
20    fn from(dims: Dim) -> Self {
21        Self {
22            dims,
23            current: Loc::default(),
24        }
25    }
26}
27
28impl Iterator for DimLocs {
29    type Item = Loc;
30
31    fn next(&mut self) -> Option<Loc> {
32        if self.current.x < self.dims.w && self.current.y < self.dims.h {
33            let loc: Loc = Loc::new(self.current.x, self.current.y);
34            self.current.x += 1;
35            if self.current.x >= self.dims.w {
36                self.current.x = 0;
37                self.current.y += 1;
38            }
39            Some(loc)
40        } else {
41            None
42        }
43    }
44
45    fn size_hint(&self) -> (usize, Option<usize>) {
46        let remaining: usize = self.dims.size()
47            - (self.current.y as usize * self.dims.w as usize + self.current.x as usize);
48        (remaining, Some(remaining))
49    }
50}
51
52impl ExactSizeIterator for DimLocs {}
53
54#[cfg(test)]
55mod tests {
56    use crate::{Dim, Loc};
57
58    #[test]
59    fn locs_order() {
60        let dim: Dim = Dim::new(2, 2);
61        let locs: Vec<Loc> = dim.locs().collect();
62        assert_eq!(
63            locs,
64            vec![
65                Loc::new(0, 0),
66                Loc::new(1, 0),
67                Loc::new(0, 1),
68                Loc::new(1, 1),
69            ]
70        );
71    }
72
73    #[test]
74    fn locs_count() {
75        let dim: Dim = Dim::new(4, 3);
76        assert_eq!(dim.locs().count(), 12);
77    }
78
79    #[test]
80    fn locs_empty() {
81        let dim: Dim = Dim::new(0, 5);
82        assert_eq!(dim.locs().count(), 0);
83    }
84
85    #[test]
86    fn locs_exact_size() {
87        let dim: Dim = Dim::new(3, 3);
88        let mut iter = dim.locs();
89        assert_eq!(iter.len(), 9);
90        iter.next();
91        assert_eq!(iter.len(), 8);
92    }
93}