1use crate::{Dim, Loc};
2use std::iter::FusedIterator;
3
4#[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}