rgeometry/data/polygon/
iter.rs

1// use claim::debug_assert_ok;
2
3use crate::data::Cursor;
4use crate::data::DirectedEdge;
5use crate::data::Point;
6use crate::TotalOrd;
7
8pub struct Iter<'a, T: 'a> {
9  pub(crate) iter: std::slice::Iter<'a, Point<T, 2>>,
10}
11impl<'a, T> Iterator for Iter<'a, T> {
12  type Item = &'a Point<T, 2>;
13  fn next(&mut self) -> Option<&'a Point<T, 2>> {
14    self.iter.next()
15  }
16}
17
18pub struct IterMut<'a, T: 'a> {
19  pub(crate) points: std::slice::IterMut<'a, Point<T, 2>>,
20}
21
22impl<'a, T> Iterator for IterMut<'a, T> {
23  type Item = &'a mut Point<T, 2>;
24  fn next(&mut self) -> Option<&'a mut Point<T, 2>> {
25    self.points.next()
26  }
27}
28
29pub struct EdgeIter<'a, T: 'a> {
30  pub(crate) iter: CursorIter<'a, T>,
31}
32
33impl<'a, T: TotalOrd + Clone> Iterator for EdgeIter<'a, T> {
34  type Item = DirectedEdge<'a, T, 2>;
35  fn next(&mut self) -> Option<Self::Item> {
36    let cursor = self.iter.next()?;
37    let this_point = cursor.point();
38    let next_point = cursor.next().point();
39    Some(DirectedEdge {
40      src: this_point,
41      dst: next_point,
42    })
43  }
44}
45
46pub struct CursorIter<'a, T: 'a> {
47  pub(crate) cursor_head: Cursor<'a, T>,
48  pub(crate) cursor_tail: Cursor<'a, T>, // inclusive
49  pub(crate) exhausted: bool,
50}
51
52impl<T> Clone for CursorIter<'_, T> {
53  fn clone(&self) -> Self {
54    CursorIter {
55      cursor_head: self.cursor_head,
56      cursor_tail: self.cursor_tail,
57      exhausted: self.exhausted,
58    }
59  }
60}
61
62impl<T: TotalOrd> PartialEq<CursorIter<'_, T>> for CursorIter<'_, T> {
63  fn eq(&self, other: &CursorIter<'_, T>) -> bool {
64    if self.len() != other.len() {
65      return false;
66    }
67    for (a, b) in self.clone().zip(other.clone()) {
68      if a.point() != b.point() {
69        return false;
70      }
71    }
72    true
73  }
74}
75
76impl<'a, T> Iterator for CursorIter<'a, T> {
77  type Item = Cursor<'a, T>;
78
79  fn next(&mut self) -> Option<Self::Item> {
80    if self.exhausted {
81      None
82    } else {
83      let out = self.cursor_head;
84      if out == self.cursor_tail {
85        self.exhausted = true;
86      } else {
87        self.cursor_head.move_next();
88      }
89      Some(out)
90    }
91  }
92
93  fn size_hint(&self) -> (usize, Option<usize>) {
94    (self.len(), Some(self.len()))
95  }
96}
97
98impl<T> ExactSizeIterator for CursorIter<'_, T> {
99  fn len(&self) -> usize {
100    let pos_head = self.cursor_head.position;
101    let pos_tail = self.cursor_tail.position;
102    if pos_head.position_id.0 <= pos_tail.position_id.0 {
103      pos_tail.position_id.0 - pos_head.position_id.0 + 1
104    } else {
105      pos_head.size - pos_head.position_id.0 + pos_tail.position_id.0 + 1
106    }
107  }
108}
109
110impl<T> DoubleEndedIterator for CursorIter<'_, T> {
111  fn next_back(&mut self) -> Option<Self::Item> {
112    if self.exhausted {
113      None
114    } else {
115      let out = self.cursor_tail;
116      if out == self.cursor_head {
117        self.exhausted = true;
118      } else {
119        self.cursor_tail.move_next();
120      }
121      Some(out)
122    }
123  }
124}