Skip to main content

grid_map/dim/
dim_locs.rs

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