Skip to main content

ring_seq/
iterators.rs

1//! Iterator types returned by [`RingSeq`](crate::RingSeq) methods.
2
3/// Sliding windows over a circular sequence.
4///
5/// Created by [`RingSeq::circular_windows`](crate::RingSeq::circular_windows)
6/// and [`RingSeq::circular_chunks`](crate::RingSeq::circular_chunks).
7#[derive(Debug, Clone)]
8pub struct SlidingO<T> {
9    pub(crate) data: Vec<T>,
10    pub(crate) window_size: usize,
11    pub(crate) step: usize,
12    pub(crate) pos: usize,
13}
14
15impl<T: Clone> Iterator for SlidingO<T> {
16    type Item = Vec<T>;
17
18    fn next(&mut self) -> Option<Self::Item> {
19        if self.pos + self.window_size > self.data.len() {
20            return None;
21        }
22        let window = self.data[self.pos..self.pos + self.window_size].to_vec();
23        self.pos += self.step;
24        Some(window)
25    }
26
27    fn size_hint(&self) -> (usize, Option<usize>) {
28        let remaining = if self.pos + self.window_size > self.data.len() {
29            0
30        } else {
31            (self.data.len() - self.pos - self.window_size) / self.step + 1
32        };
33        (remaining, Some(remaining))
34    }
35}
36
37impl<T: Clone> ExactSizeIterator for SlidingO<T> {}
38
39// ---------------------------------------------------------------------------
40// Helpers shared by the iterators below
41// ---------------------------------------------------------------------------
42
43fn rotate_clone<T: Clone>(ring: &[T], i: usize) -> Vec<T> {
44    let n = ring.len();
45    if n == 0 {
46        return vec![];
47    }
48    let i = i % n;
49    let mut v = Vec::with_capacity(n);
50    v.extend_from_slice(&ring[i..]);
51    v.extend_from_slice(&ring[..i]);
52    v
53}
54
55fn reflect_at_zero<T: Clone>(ring: &[T]) -> Vec<T> {
56    if ring.is_empty() {
57        return vec![];
58    }
59    // reflect_at(0) = start_at(1).reverse()
60    let mut v = Vec::with_capacity(ring.len());
61    v.extend_from_slice(&ring[1..]);
62    v.extend_from_slice(&ring[..1]);
63    v.reverse();
64    v
65}
66
67// ---------------------------------------------------------------------------
68// Rotations
69// ---------------------------------------------------------------------------
70
71/// All rotations of a circular sequence.
72///
73/// Created by [`RingSeq::rotations`](crate::RingSeq::rotations).
74/// Yields `n` items for a non-empty ring (one per starting position),
75/// or a single empty `Vec` for an empty ring.
76#[derive(Debug, Clone)]
77pub struct Rotations<'a, T> {
78    pub(crate) ring: &'a [T],
79    pub(crate) index: usize,
80    pub(crate) total: usize,
81}
82
83impl<T: Clone> Iterator for Rotations<'_, T> {
84    type Item = Vec<T>;
85
86    fn next(&mut self) -> Option<Self::Item> {
87        if self.index >= self.total {
88            return None;
89        }
90        let result = rotate_clone(self.ring, self.index);
91        self.index += 1;
92        Some(result)
93    }
94
95    fn size_hint(&self) -> (usize, Option<usize>) {
96        let r = self.total - self.index;
97        (r, Some(r))
98    }
99}
100
101impl<T: Clone> ExactSizeIterator for Rotations<'_, T> {}
102
103// ---------------------------------------------------------------------------
104// Reflections
105// ---------------------------------------------------------------------------
106
107/// The two orientations of a circular sequence: the original and its
108/// reflection at index 0.
109///
110/// Created by [`RingSeq::reflections`](crate::RingSeq::reflections).
111/// Yields 2 items for a non-empty ring, or a single empty `Vec` for an
112/// empty ring.
113#[derive(Debug, Clone)]
114pub struct Reflections<'a, T> {
115    pub(crate) ring: &'a [T],
116    pub(crate) state: u8,
117}
118
119impl<T: Clone> Iterator for Reflections<'_, T> {
120    type Item = Vec<T>;
121
122    fn next(&mut self) -> Option<Self::Item> {
123        match self.state {
124            0 => {
125                self.state = if self.ring.is_empty() { 2 } else { 1 };
126                Some(self.ring.to_vec())
127            }
128            1 => {
129                self.state = 2;
130                Some(reflect_at_zero(self.ring))
131            }
132            _ => None,
133        }
134    }
135
136    fn size_hint(&self) -> (usize, Option<usize>) {
137        let r = match self.state {
138            0 => {
139                if self.ring.is_empty() {
140                    1
141                } else {
142                    2
143                }
144            }
145            1 => 1,
146            _ => 0,
147        };
148        (r, Some(r))
149    }
150}
151
152impl<T: Clone> ExactSizeIterator for Reflections<'_, T> {}
153
154// ---------------------------------------------------------------------------
155// Reversions
156// ---------------------------------------------------------------------------
157
158/// The two orientations of a circular sequence: the original and its
159/// reversal.
160///
161/// Created by [`RingSeq::reversions`](crate::RingSeq::reversions).
162/// Yields 2 items for a non-empty ring, or a single empty `Vec` for an
163/// empty ring.
164#[derive(Debug, Clone)]
165pub struct Reversions<'a, T> {
166    pub(crate) ring: &'a [T],
167    pub(crate) state: u8,
168}
169
170impl<T: Clone> Iterator for Reversions<'_, T> {
171    type Item = Vec<T>;
172
173    fn next(&mut self) -> Option<Self::Item> {
174        match self.state {
175            0 => {
176                self.state = if self.ring.is_empty() { 2 } else { 1 };
177                Some(self.ring.to_vec())
178            }
179            1 => {
180                self.state = 2;
181                let mut v = self.ring.to_vec();
182                v.reverse();
183                Some(v)
184            }
185            _ => None,
186        }
187    }
188
189    fn size_hint(&self) -> (usize, Option<usize>) {
190        let r = match self.state {
191            0 => {
192                if self.ring.is_empty() {
193                    1
194                } else {
195                    2
196                }
197            }
198            1 => 1,
199            _ => 0,
200        };
201        (r, Some(r))
202    }
203}
204
205impl<T: Clone> ExactSizeIterator for Reversions<'_, T> {}
206
207// ---------------------------------------------------------------------------
208// RotationsAndReflections
209// ---------------------------------------------------------------------------
210
211/// All rotations of the original sequence followed by all rotations of its
212/// reflection.
213///
214/// Created by
215/// [`RingSeq::rotations_and_reflections`](crate::RingSeq::rotations_and_reflections).
216/// Yields `2n` items for a non-empty ring, or a single empty `Vec` for an
217/// empty ring.
218#[derive(Debug, Clone)]
219pub struct RotationsAndReflections<'a, T> {
220    pub(crate) ring: &'a [T],
221    pub(crate) reflected: Vec<T>,
222    pub(crate) index: usize,
223    pub(crate) total: usize,
224}
225
226impl<T: Clone> Iterator for RotationsAndReflections<'_, T> {
227    type Item = Vec<T>;
228
229    fn next(&mut self) -> Option<Self::Item> {
230        if self.index >= self.total {
231            return None;
232        }
233        let n = self.ring.len();
234        if n == 0 {
235            // Empty ring: yield one empty vec
236            self.index += 1;
237            return Some(vec![]);
238        }
239        let (source, rot) = if self.index < n {
240            (self.ring, self.index)
241        } else {
242            (self.reflected.as_slice(), self.index - n)
243        };
244        self.index += 1;
245        Some(rotate_clone(source, rot))
246    }
247
248    fn size_hint(&self) -> (usize, Option<usize>) {
249        let r = self.total - self.index;
250        (r, Some(r))
251    }
252}
253
254impl<T: Clone> ExactSizeIterator for RotationsAndReflections<'_, T> {}