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}