1use crate::{Dim, Loc};
2
3impl Dim {
4 pub fn locs(self) -> DimLocs {
8 DimLocs::from(self)
9 }
10}
11
12#[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}