prev_iter/
lib.rs

1//! `prev-iter` contains an iterator which allows you to view the previous element.
2
3use std::iter::Iterator;
4use std::iter::Peekable;
5
6/// An iterator with `prev()`, `prev_peek()`, and `peek()` functions that return the previous element, a
7/// reference to the previous element, or a reference to the next element, respectively.
8///
9/// This `struct` is created by passing an [`Iterator`] whose `Item` implements [`Clone`] to the
10/// [`new`] function.
11///
12/// [`Iterator`]: https://doc.rust-lang.org/nightly/core/iter/iterator/trait.Iterator.html
13/// [`Clone`]: https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html
14/// [`new`]: struct.PrevPeekable.html#method.new
15#[derive(Debug)]
16pub struct PrevPeekable<I>
17where
18    I: Iterator,
19    <I as ::std::iter::Iterator>::Item: ::std::clone::Clone,
20{
21    /// Iterator that `PrevPeekable` wraps
22    iterator: Peekable<I>,
23    /// The element before the one we just returned. Initially it's `None`.
24    prev: Option<I::Item>,
25    /// The current element we just returned.
26    current: Option<I::Item>,
27    /// Keeps track of whether the iterator has reached the end or not
28    finished: bool,
29}
30
31impl<I> PrevPeekable<I>
32where
33    I: Iterator,
34    <I as ::std::iter::Iterator>::Item: ::std::clone::Clone,
35{
36    /// Creates a new `PrevPeekable`. It takes an [`Iterator`] whose `Item` implements [`Clone`].
37    ///
38    /// [`Iterator`]: https://doc.rust-lang.org/nightly/core/iter/iterator/trait.Iterator.html
39    /// [`Clone`]: https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html
40    ///
41    /// # Examples
42    ///
43    /// Basic usage:
44    ///
45    /// ```
46    /// use prev_iter::PrevPeekable;
47    ///
48    /// let v = vec![1, 2, 3];
49    /// let mut iter = PrevPeekable::new(v.iter());
50    ///
51    /// assert_eq!(Some(&1), iter.next());
52    /// assert_eq!(Some(&2), iter.next());
53    /// assert_eq!(Some(&1), iter.prev());
54    /// ```
55    pub fn new(iterator: I) -> Self {
56        PrevPeekable {
57            iterator: iterator.peekable(),
58            prev: None,
59            current: None,
60            finished: false,
61        }
62    }
63
64    /// Returns a reference to the `next()` value without advancing the iterator.
65    ///
66    /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`.
67    /// But if the iteration is over, `None` is returned.
68    ///
69    /// [`next`]: https://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#tymethod.next
70    ///
71    /// Because `peek()` returns a reference, and many iterators iterate over
72    /// references, there can be a possibly confusing situation where the
73    /// return value is a double reference. You can see this effect in the
74    /// examples below.
75    ///
76    /// # Examples
77    ///
78    /// Basic usage:
79    ///
80    /// ```
81    /// let xs = [1, 2, 3];
82    ///
83    /// let mut iter = xs.iter().peekable();
84    ///
85    /// // peek() lets us see into the future
86    /// assert_eq!(iter.peek(), Some(&&1));
87    /// assert_eq!(iter.next(), Some(&1));
88    ///
89    /// assert_eq!(iter.next(), Some(&2));
90    ///
91    /// // The iterator does not advance even if we `peek` multiple times
92    /// assert_eq!(iter.peek(), Some(&&3));
93    /// assert_eq!(iter.peek(), Some(&&3));
94    ///
95    /// assert_eq!(iter.next(), Some(&3));
96    ///
97    /// // After the iterator is finished, so is `peek()`
98    /// assert_eq!(iter.peek(), None);
99    /// assert_eq!(iter.next(), None);
100    /// ```
101    pub fn peek(&mut self) -> Option<&I::Item> {
102        self.iterator.peek()
103    }
104
105    /// Returns the previous value in the iterator without moving the iterator backwards.
106    /// When the end is reached, it will always return the last element.
107    ///
108    /// This function performs a `clone()` when returning the data.
109    ///
110    /// # Examples
111    ///
112    /// Basic usage:
113    ///
114    /// ```
115    /// use prev_iter::PrevPeekable;
116    ///
117    /// let v = vec![1, 2];
118    /// let mut it = PrevPeekable::new(v.iter());
119    ///
120    /// // When the iterator is initialized there is not previous value
121    /// assert_eq!(None, it.prev());
122    /// assert_eq!(Some(&1), it.next());
123    ///
124    /// // There is no value before the first element
125    /// assert_eq!(None, it.prev());
126    /// assert_eq!(Some(&2), it.next());
127    ///
128    /// // Previous value before 2 is 1
129    /// assert_eq!(Some(&1), it.prev());
130    ///
131    /// // The iterator doesn't have anymore values so the prev() will always
132    /// // return the last element
133    /// assert_eq!(None, it.next());
134    /// assert_eq!(Some(&2), it.prev());
135    /// ```
136    pub fn prev(&self) -> Option<I::Item> {
137        self.prev.clone()
138    }
139
140    /// Returns a reference to the previous value in the iterator without moving the iterator
141    /// backwards. When the end is reached, it will always return the last element.
142    ///
143    /// Because `prev_peek()` returns a reference, and many iterators iterate over
144    /// references, there can be a possibly confusing situation where the
145    /// return value is a double reference. You can see this effect in the
146    /// examples below.
147    ///
148    /// # Examples
149    ///
150    /// Basic usage:
151    ///
152    /// ```
153    /// use prev_iter::PrevPeekable;
154    ///
155    /// let v = vec![1, 2];
156    /// let mut it = PrevPeekable::new(v.iter());
157    ///
158    /// // Initially there is nothing to peek at
159    /// assert_eq!(None, it.prev_peek());
160    /// assert_eq!(Some(&1), it.next());
161    ///
162    /// // There is nothing before the first element
163    /// assert_eq!(None, it.prev_peek());
164    /// assert_eq!(Some(&2), it.next());
165    ///
166    /// // 1 comes before 2
167    /// assert_eq!(Some(&&1), it.prev_peek());
168    /// assert_eq!(None, it.next());
169    ///
170    /// // 2 will always be returned as the last element
171    /// assert_eq!(Some(&&2), it.prev_peek());
172    /// ```
173    pub fn prev_peek(&self) -> Option<&I::Item> {
174        self.prev.as_ref()
175    }
176}
177
178impl<I> Iterator for PrevPeekable<I>
179where
180    I: Iterator,
181    <I as ::std::iter::Iterator>::Item: ::std::clone::Clone,
182{
183    type Item = I::Item;
184
185    fn next(&mut self) -> Option<I::Item> {
186        // If self.iterator.peek() is None, we've reached the end, and self.prev should
187        // the second last element
188        if self.iterator.peek().is_some() {
189            self.prev = std::mem::replace(&mut self.current, self.iterator.next());
190            return self.current.clone();
191        } else if !self.finished {
192            self.prev = std::mem::replace(&mut self.current, self.iterator.next());
193            self.finished = true;
194        }
195
196        None
197    }
198}
199
200#[cfg(test)]
201mod tests {
202    use super::*;
203
204    macro_rules! iter {
205        ($v: expr) => {{
206            PrevPeekable::new($v.iter())
207        }};
208    }
209
210    #[test]
211    fn test_next() {
212        let v = vec![1, 2, 3];
213        let mut iter = iter!(v);
214
215        assert_eq!(Some(&1), iter.next());
216        assert_eq!(None, iter.prev);
217        assert_eq!(Some(&2), iter.next());
218        assert_eq!(Some(&1), iter.prev);
219        assert_eq!(Some(&3), iter.next());
220        assert_eq!(Some(&2), iter.prev);
221        assert_eq!(None, iter.next());
222        assert_eq!(None, iter.next());
223    }
224
225    #[test]
226    fn test_peek() {
227        let v = vec![1, 2];
228        let mut iter = iter!(v);
229
230        assert_eq!(Some(&&1), iter.peek());
231        assert_eq!(Some(&1), iter.next());
232        assert_eq!(Some(&&2), iter.peek());
233        assert_eq!(Some(&2), iter.next());
234        assert_eq!(None, iter.next());
235    }
236
237    #[test]
238    fn test_prev() {
239        let v = vec![1, 2];
240        let mut it = iter!(v);
241
242        assert_eq!(None, it.prev());
243        assert_eq!(Some(&1), it.next());
244        assert_eq!(None, it.prev());
245        assert_eq!(Some(&2), it.next());
246        assert_eq!(Some(&1), it.prev());
247        assert_eq!(None, it.next());
248        assert_eq!(Some(&2), it.prev());
249
250        assert_eq!(None, it.next());
251        assert_eq!(Some(&2), it.prev());
252    }
253
254    #[test]
255    fn test_prev_peek() {
256        let v = vec![1, 2];
257        let mut it = iter!(v);
258
259        assert_eq!(None, it.prev_peek());
260        assert_eq!(Some(&1), it.next());
261        assert_eq!(None, it.prev_peek());
262        assert_eq!(Some(&2), it.next());
263        assert_eq!(Some(&&1), it.prev_peek());
264        assert_eq!(None, it.next());
265        assert_eq!(Some(&&2), it.prev_peek());
266
267        assert_eq!(None, it.next());
268        assert_eq!(Some(&&2), it.prev_peek());
269    }
270}