picto/iter/
coordinates.rs1use crate::region::Region;
16
17#[derive(Eq, PartialEq, Debug)]
19pub struct Coordinates {
20 x: u32,
21 y: u32,
22
23 region: Region,
24}
25
26impl Coordinates {
27 #[inline]
29 pub fn new(region: Region) -> Self {
30 Coordinates { x: 0, y: 0, region }
31 }
32
33 #[inline]
35 pub fn region(&self) -> Region {
36 self.region
37 }
38}
39
40impl Iterator for Coordinates {
41 type Item = (u32, u32);
42
43 #[inline]
44 fn next(&mut self) -> Option<Self::Item> {
45 if self.x >= self.region.width {
46 self.x = 0;
47 self.y += 1;
48 }
49
50 if self.y >= self.region.height {
51 return None;
52 }
53
54 self.x += 1;
55
56 Some((self.x - 1 + self.region.x, self.y + self.region.y))
57 }
58
59 #[inline]
60 fn size_hint(&self) -> (usize, Option<usize>) {
61 (self.len(), Some(self.len()))
62 }
63}
64
65impl ExactSizeIterator for Coordinates {
66 #[inline]
67 fn len(&self) -> usize {
68 let length = self.region.width * self.region.height;
69 let remaining = length - (self.y * self.region.width + self.x);
70
71 remaining as usize
72 }
73}
74
75#[cfg(test)]
76mod test {
77 use super::*;
78 use crate::region::Region;
79
80 #[test]
81 fn size_hint() {
82 let mut coord = Coordinates::new(Region::from(0, 0, 2, 2));
83
84 assert_eq!(4, coord.size_hint().0);
85 coord.next().unwrap();
86 assert_eq!(3, coord.size_hint().0);
87 coord.next().unwrap();
88 assert_eq!(2, coord.size_hint().0);
89 coord.next().unwrap();
90 assert_eq!(1, coord.size_hint().0);
91 coord.next().unwrap();
92 assert_eq!(0, coord.size_hint().0);
93 }
94}