peekmore/
lib.rs

1#![no_std]
2#![deny(missing_docs)]
3#![deny(clippy::all)]
4
5//! **Synopsis:**
6//!
7//! This crate introduces a multi-peekable iterator.
8//! The iterator is similar to [`Peekable`]. The main difference is that [`Peekable`] only
9//! allows you to peek at the next element and no further. When using `PeekMore` however,
10//! you can peek at as many elements as you want.
11//!
12//! **A peek at how it works:**
13//!
14//! To enable peeking at multiple elements ahead of consuming a next element, the iterator uses a
15//! traversable queue which holds the elements which you can peek at, but have not been
16//! consumed (yet).
17//! The underlying data structure of this queue can be a `Vec`, or a `SmallVec` from the smallvec crate.
18//! By default, the `SmallVec` is used. SmallVec uses the stack for a limited amount of elements and
19//! will only allocate on the heap if this maximum amount of elements is reached.
20//!
21//!
22//! **Illustrated example:**
23//!
24//! An illustrated example can be found at the [`PeekMoreIterator::peek`] documentation.
25//!
26//!
27//! **Usage example:**
28//!
29//! ```rust
30//! use peekmore::PeekMore;
31//!
32//! let iterable = [1, 2, 3, 4];
33//! let mut iter = iterable.iter().peekmore();
34//!
35//! // Peek at the first element.
36//! let v1 = iter.peek();
37//! assert_eq!(v1, Some(&&1));
38//!
39//! // Consume the first element.
40//! let v1c = iter.next();
41//! assert_eq!(v1c, Some(&1));
42//!
43//! // Peek at the second element (the element our cursor points at also moved to the second element,
44//! // since the first element was consumed.)
45//! let v2 = iter.peek();
46//! assert_eq!(v2, Some(&&2));
47//!
48//! // Advance the cursor. The cursor will now point to the third element.
49//! let _ = iter.advance_cursor();
50//!
51//! // Check that it is indeed at the third element.
52//! let v3 = iter.peek();
53//! assert_eq!(v3, Some(&&3));
54//!
55//! // Reset the position the cursor points at. The cursor will point to the first unconsumed element
56//! // again.
57//! iter.reset_cursor();
58//!
59//! // Check that we are indeed at the second element again.
60//! let v2 = iter.peek();
61//! assert_eq!(v2, Some(&&2));
62//!
63//! // Shift the position of the cursor to the right twice by chaining the advance_view method.
64//! let _ = iter.advance_cursor().advance_cursor();
65//!
66//! // Verify that the cursor indeed points at the fourth element.
67//! let v4 = iter.peek();
68//! assert_eq!(v4, Some(&&4));
69//!
70//! // Reset the position which the cursor points at again.
71//! iter.reset_cursor();
72//!
73//! // We can also advance the cursor and peek with a single operation.
74//! let v3 = iter.peek_next();
75//! assert_eq!(v3, Some(&&3));
76//! ```
77//!
78//!
79//! [`Peekable`]: https://doc.rust-lang.org/core/iter/struct.Peekable.html
80//! [`PeekMoreIterator::peek`]: struct.PeekMoreIterator.html#method.peek
81//! [requires]: https://github.com/servo/rust-smallvec/issues/160
82
83/// We need to allocate elements which haven't been consumed by the PeekMore iterator.
84extern crate alloc;
85
86/// Import std only when running doc tests without errors. Std will not be included outside of
87/// doctest based binaries.
88///
89/// See [rust#54010](https://github.com/rust-lang/rust/issues/54010) for the error thrown by `doctest`
90/// if no allocator is present (e.g. with just core/alloc).
91/// Note that `cfg(doctest)` requires Rust 1.40 ([tracking issue](https://github.com/rust-lang/rust/issues/62210)).
92/// As a result of the above, `doctest` is disabled on the CI for Rust versions below `1.40`.
93#[cfg(doctest)]
94extern crate std;
95
96/// Use the system allocator when running doc tests.
97///
98/// See [rust#54010](https://github.com/rust-lang/rust/issues/54010) for the error thrown by `doctest`
99/// if no allocator is present (e.g. with just core/alloc).
100/// Note that `cfg(doctest)` requires Rust 1.40 ([tracking issue](https://github.com/rust-lang/rust/issues/62210)).
101/// As a result of the above, `doctest` is disabled on the CI for Rust versions below `1.40`.
102#[cfg(doctest)]
103#[global_allocator]
104static A: std::alloc::System = std::alloc::System;
105
106use core::iter::FusedIterator;
107
108/// Use a `Vec` to queue iterator elements if the `smallvec` feature is disabled.
109#[cfg(not(feature = "smallvec"))]
110use alloc::vec::Vec;
111
112/// Use a SmallVec to queue iterator elements instead of a Vec, if the `smallvec` feature is enabled
113/// (default).
114#[cfg(feature = "smallvec")]
115use smallvec::SmallVec;
116
117/// Trait which allows you to create the multi-peek iterator.
118/// It allows you to peek at any unconsumed element.
119/// Elements can be consumed using the [`next`] method defined on any [`Iterator`].
120///
121/// [`next`]: https://doc.rust-lang.org/core/iter/trait.Iterator.html#tymethod.next
122/// [`Iterator`]: https://doc.rust-lang.org/core/iter/trait.Iterator.html
123pub trait PeekMore: Iterator + Sized {
124    /// Create a multi-peek iterator where we can peek forward multiple times from an existing iterator.
125    fn peekmore(self) -> PeekMoreIterator<Self>;
126}
127
128impl<I: Iterator> PeekMore for I {
129    fn peekmore(self) -> PeekMoreIterator<I> {
130        PeekMoreIterator {
131            iterator: self,
132
133            #[cfg(not(feature = "smallvec"))]
134            queue: Vec::new(),
135
136            #[cfg(feature = "smallvec")]
137            queue: SmallVec::new(),
138
139            cursor: 0usize,
140        }
141    }
142}
143
144/// Default stack size for SmallVec.
145/// Admittedly the current size is chosen quite arbitrarily.
146#[cfg(feature = "smallvec")]
147const DEFAULT_STACK_SIZE: usize = 8;
148
149/// This iterator makes it possible to peek multiple times without consuming a value.
150/// In reality the underlying iterator will be consumed, but the values will be stored in a queue.
151/// This queue allows us to peek at unconsumed elements (as far as the multi-peek iterator is concerned).
152/// When the iterator [consumes] an element, the element at the front of the queue will be dequeued,
153/// and will no longer be peekable.
154///
155/// [consumes]: https://doc.rust-lang.org/core/iter/trait.Iterator.html#tymethod.next
156#[derive(Clone, Debug)]
157pub struct PeekMoreIterator<I: Iterator> {
158    /// The underlying iterator. Consumption of this inner iterator does not represent consumption of the
159    /// `PeekMoreIterator`.
160    iterator: I,
161
162    /// The queue represents the items of our iterator which have not been consumed, but can be peeked
163    /// at without consuming them. Once an element has been consumed by the iterator, the element will
164    /// be dequeued and it will no longer be possible to peek at this element.
165    #[cfg(not(feature = "smallvec"))]
166    queue: Vec<Option<I::Item>>,
167    #[cfg(feature = "smallvec")]
168    queue: SmallVec<[Option<I::Item>; DEFAULT_STACK_SIZE]>,
169
170    /// The cursor points to the element we are currently peeking at.
171    ///
172    /// The cursor will point to the first unconsumed element if the value is `0`, the second if it is
173    /// `1`, and so forth. Peeking at the 0th cursor element is equivalent to peeking with
174    /// [`core::iter::Peekable::peek`].
175    ///
176    /// [`core::iter::Peekable::peek`]: https://doc.rust-lang.org/core/iter/struct.Peekable.html#method.peek
177    cursor: usize,
178}
179
180impl<I: Iterator> PeekMoreIterator<I> {
181    /// Get a reference to the element where the cursor currently points to. If no such element exists,
182    /// return `None` will be returned.
183    ///
184    /// If we haven't advanced our cursor, it will point to the same element as `Iterator::next()` would
185    /// return.
186    /// Note that the cursor can't point to an element before the first unconsumed element within
187    /// the iterator. In a sense the cursor moves independently within the iterator.
188    /// But it can only point to unconsumed elements.
189    ///
190    /// The following illustration aims to show how `peek()` behaves. `i` represents the position
191    /// of the iterator (i.e. the next value that will be returned if `next()` is called) and `j`
192    /// represents the position of the cursor (i.e. the current element referenced if
193    /// `peek()` is called).
194    /// In example code next to the illustrations, the first element `1` is analogous to `A`,
195    /// `2` to `B`, etc.
196    ///
197    /// The example below primarily uses `advance_cursor()` to move the cursor and `peek()` to
198    /// peek at the element the cursor points to, but many often more convenient methods exist to
199    /// change the element cursor points at, or to peek at those elements.
200    ///
201    /// * Let's start:
202    ///
203    /// ```rust
204    /// use peekmore::PeekMore;
205    ///
206    /// // Initialize our iterator.
207    /// let iterable = [1, 2, 3, 4];
208    /// let mut iterator = iterable.iter().peekmore();
209    /// ```
210    ///
211    /// ```txt
212    /// -----     -----      -----     -----
213    /// | A | --> | B |  --> | C | --> | D | --> None --> None --> ...
214    /// -----     -----      -----     -----
215    ///   ^
216    ///   i, j
217    /// ```
218    ///
219    /// * Call `peek()`:
220    ///
221    /// ```rust
222    /// # use peekmore::PeekMore;
223    /// # let iterable = [1, 2, 3, 4];
224    /// # let mut iterator = iterable.iter().peekmore();
225    /// let j = iterator.peek();
226    /// assert_eq!(j, Some(&&1));
227    /// ```
228    ///
229    /// ```txt
230    /// -----     -----      -----     -----
231    /// | A | --> | B |  --> | C | --> | D | --> None --> None --> ...
232    /// -----     -----      -----     -----
233    ///   ^
234    ///   i, j
235    ///      returns Some(&A)
236    ///
237    /// ```
238    ///
239    /// * Call `advance_cursor()`
240    ///
241    /// ```rust
242    /// # use peekmore::PeekMore;
243    /// # let iterable = [1, 2, 3, 4];
244    /// # let mut iterator = iterable.iter().peekmore();
245    /// let iter = iterator.advance_cursor();
246    /// ```
247    ///
248    /// ```txt
249    /// -----     -----      -----     -----
250    /// | A | --> | B |  --> | C | --> | D | --> None --> None --> ...
251    /// -----     -----      -----     -----
252    ///   ^         ^
253    ///   i         j
254    /// ```
255    ///
256    /// * Call `peek()`
257    ///
258    /// The reference returned by `peek()` will not change, similar to the behaviour of
259    /// [`core::iter::Peekable::peek`]. In order to move to the next peekable element, we need to
260    /// advance the cursor.
261    ///
262    /// ```rust
263    /// # use peekmore::PeekMore;
264    /// # let iterable = [1, 2, 3, 4];
265    /// # let mut iterator = iterable.iter().peekmore();
266    /// # let iter = iterator.advance_cursor();
267    /// let j = iterator.peek();
268    /// assert_eq!(j, Some(&&2));
269    ///
270    /// // Calling `peek()` multiple times doesn't shift the position of the cursor;
271    /// // a reference to the same element will be returned each call.
272    /// assert_eq!(iterator.peek(), Some(&&2));
273    /// assert_eq!(iterator.peek(), Some(&&2));
274    /// ```
275    ///
276    /// ```txt
277    /// -----     -----      -----     -----
278    /// | A | --> | B |  --> | C | --> | D | --> None --> None --> ...
279    /// -----     -----      -----     -----
280    ///   ^         ^
281    ///   i         j
282    ///             returns Some(&B)
283    /// ```
284    ///
285    ///
286    /// * Call `next()`
287    ///
288    /// By calling next, the underlying iterator will be advanced andthe element represented by `A`
289    /// will be consumed. It won't be possible to peek at `A` anymore.
290    ///
291    /// ```rust
292    /// # use peekmore::PeekMore;
293    /// # let iterable = [1, 2, 3, 4];
294    /// # let mut iterator = iterable.iter().peekmore();
295    /// # let iter = iterator.advance_cursor();
296    /// let i = iterator.next();
297    /// assert_eq!(i, Some(&1));
298    /// ```
299    ///
300    /// ```txt
301    /// -----     -----      -----     -----
302    /// | A |     | B |  --> | C | --> | D | --> None --> None --> ...
303    /// -----     -----      -----     -----
304    ///             ^
305    ///             i, j
306    ///  returns Some(A)
307    /// ```
308    ///
309    /// * Call `next()`.
310    ///
311    /// The underlying iterator is advanced again.
312    /// As a result, the cursor position also shifts to the next iterator position, which happens if
313    /// the underlying iterator consumed an element where our cursor pointed at (that is if `j < i`).
314    ///
315    ///
316    /// ```rust
317    /// # use peekmore::PeekMore;
318    /// # let iterable = [1, 2, 3, 4];
319    /// # let mut iterator = iterable.iter().peekmore();
320    /// # let iter = iterator.advance_cursor();
321    /// # let _ = iterator.next();
322    /// // Show that the cursor still points at the second element.
323    /// let j = iterator.peek();
324    /// assert_eq!(j, Some(&&2));
325    ///
326    /// // Consume the second element.
327    /// let i = iterator.next();
328    /// assert_eq!(i, Some(&2));
329    ///
330    /// // Our cursor previously pointed at the element represented by B. Since that element has
331    /// // been consumed, the cursor shifts to the next unconsumed element: C.
332    /// let j = iterator.peek();
333    /// assert_eq!(j, Some(&&3));
334    ///
335    ///
336    /// ```
337    ///
338    /// ```txt
339    /// -----     -----      -----     -----
340    /// | A |     | B |      | C | --> | D | --> None --> None --> ...
341    /// -----     -----      -----     -----
342    ///                        ^
343    ///                        i, j
344    ///           returns Some(B)
345    /// ```
346    ///
347    /// * Consume more elements by calling `next()` until we reach `None`:
348    ///
349    /// ```rust
350    /// # use peekmore::PeekMore;
351    /// # let iterable = [1, 2, 3, 4];
352    /// # let mut iterator = iterable.iter().peekmore();
353    /// # let iter = iterator.advance_cursor();
354    /// # let _ = iterator.next();
355    /// # let j = iterator.peek();
356    /// # assert_eq!(j, Some(&&2));
357    /// # let i = iterator.next();
358    /// # assert_eq!(i, Some(&2));
359    /// # let j = iterator.peek();
360    /// # assert_eq!(j, Some(&&3));
361    /// let i = iterator.next();
362    /// assert_eq!(i, Some(&3));
363    ///
364    /// let j = iterator.peek();
365    /// assert_eq!(j, Some(&&4));
366    ///
367    /// let i = iterator.next();
368    /// assert_eq!(i, Some(&4));
369    ///
370    /// let j = iterator.peek();
371    /// assert_eq!(j, None);
372    ///
373    /// let i = iterator.next();
374    /// assert_eq!(i, None);
375    /// ```
376    /// [`core::iter::Peekable::peek`]: https://doc.rust-lang.org/core/iter/struct.Peekable.html#method.peek
377    #[inline]
378    pub fn peek(&mut self) -> Option<&I::Item> {
379        self.fill_queue(self.cursor);
380        self.queue.get(self.cursor).and_then(|v| v.as_ref())
381    }
382
383    /// Peeks at the first unconsumed element, regardless of where the cursor currently is.
384    #[inline]
385    pub fn peek_first(&mut self) -> Option<&I::Item> {
386        self.peek_nth(0)
387    }
388
389    // Convenient as we don't have to re-assign our mutable borrow on the 'user' side.
390    /// Advance the cursor to the next element and return a reference to that value.
391    #[inline]
392    pub fn peek_next(&mut self) -> Option<&I::Item> {
393        let this = self.advance_cursor();
394        this.peek()
395    }
396
397    /// Try to peek at a previous element. If no such element exists, an `Err` result containing a
398    /// [`PeekMoreError::ElementHasBeenConsumed`] will be returned.
399    ///
400    /// If a previous element does exist, an option wrapped in an `Ok` result will be returned.
401    ///
402    /// [`PeekMoreError::ElementHasBeenConsumed`]: enum.PeekMoreError.html#variant.ElementHasBeenConsumed
403    #[inline]
404    pub fn peek_previous(&mut self) -> Result<Option<&I::Item>, PeekMoreError> {
405        if self.cursor >= 1 {
406            self.move_cursor_back().map(|iter| iter.peek())
407        } else {
408            Err(PeekMoreError::ElementHasBeenConsumed)
409        }
410    }
411
412    /// Move the cursor `n` steps forward and peek at the element the cursor then points to.
413    #[inline]
414    pub fn peek_forward(&mut self, n: usize) -> Option<&I::Item> {
415        let this = self.advance_cursor_by(n);
416        this.peek()
417    }
418
419    /// Move the cursor `n` steps backward and peek at the element the cursor then points to.
420    ///
421    /// If there aren't `n` elements prior to the element the cursor currently points at, a
422    /// [`PeekMoreError::ElementHasBeenConsumed`] is returned instead.
423    /// The cursor will then stay at the position it was prior to calling this method.
424    ///
425    /// If you want to peek at the first unconsumed element instead of returning with an error, you
426    /// can use the [`peek_backward_or_first`] method instead.
427    ///
428    /// [`PeekMoreError::ElementHasBeenConsumed`]: enum.PeekMoreError.html#variant.ElementHasBeenConsumed
429    /// [`peek_backward_or_first`]: struct.PeekMoreIterator.html#method.peek_backward_or_first
430    #[inline]
431    pub fn peek_backward(&mut self, n: usize) -> Result<Option<&I::Item>, PeekMoreError> {
432        let _ = self.move_cursor_back_by(n)?;
433
434        Ok(self.peek())
435    }
436
437    /// Move the cursor `n` steps backward and peek at the element the cursor then points to, or
438    /// if there aren't `n` elements prior to the element the cursor currently points to, peek at
439    /// the first unconsumed element instead.
440    #[inline]
441    pub fn peek_backward_or_first(&mut self, n: usize) -> Option<&I::Item> {
442        if self.move_cursor_back_by(n).is_err() {
443            self.reset_cursor();
444        }
445
446        self.peek()
447    }
448
449    /// Peek at the nth element without moving the cursor.
450    #[inline]
451    pub fn peek_nth(&mut self, n: usize) -> Option<&I::Item> {
452        self.fill_queue(n);
453        self.queue.get(n).and_then(|v| v.as_ref())
454    }
455
456    /// Advance the cursor to the next peekable element.
457    ///
458    /// This method does not advance the iterator itself. To advance the iterator, call [`next()`]
459    /// instead.
460    ///
461    /// A mutable reference to the iterator is returned, which allows the operation to be chained.
462    ///
463    /// [`next()`]: struct.PeekMoreIterator.html#impl-Iterator
464    #[inline]
465    pub fn advance_cursor(&mut self) -> &mut PeekMoreIterator<I> {
466        self.increment_cursor();
467        self
468    }
469
470    /// Advance the cursor `n` elements forward.
471    ///
472    /// This does not advance the iterator itself. To advance the iterator, call [`next()`] instead.
473    ///
474    /// [`next()`]: struct.PeekMoreIterator.html#impl-Iterator
475    #[inline]
476    pub fn advance_cursor_by(&mut self, n: usize) -> &mut PeekMoreIterator<I> {
477        self.cursor += n;
478        self
479    }
480
481    /// Moves the cursor forward until the predicate is no longer `true`.
482    ///
483    /// After this method returns, the cursor points to the first element that fails `predicate`. If no peeked elements
484    /// pass `predicate` then the cursor will remain unchanged.
485    ///
486    /// This does not advance the iterator itself. To advance the iterator, call [`next()`] instead.
487    ///
488    /// [`next()`]: struct.PeekMoreIterator.html#impl-Iterator
489    #[inline]
490    pub fn advance_cursor_while<P: Fn(Option<&I::Item>) -> bool>(
491        &mut self,
492        predicate: P,
493    ) -> &mut PeekMoreIterator<I> {
494        let view = self.peek();
495
496        if predicate(view) {
497            self.increment_cursor();
498            self.advance_cursor_while(predicate)
499        } else {
500            self
501        }
502    }
503
504    /// Move the cursor to the previous peekable element.
505    /// If such an element doesn't exist, a [`PeekMoreError::ElementHasBeenConsumed`] will be
506    /// returned.
507    ///
508    /// If we can move to a previous element, a mutable reference to the iterator,
509    /// wrapped in the `Ok` variant of `Result` will be returned.
510    ///
511    /// [`PeekMoreError::ElementHasBeenConsumed`]: enum.PeekMoreError.html#variant.ElementHasBeenConsumed
512    #[inline]
513    pub fn move_cursor_back(&mut self) -> Result<&mut PeekMoreIterator<I>, PeekMoreError> {
514        if self.cursor >= 1 {
515            self.decrement_cursor();
516            Ok(self)
517        } else {
518            Err(PeekMoreError::ElementHasBeenConsumed)
519        }
520    }
521
522    /// Move the cursor `n` elements backward. If there aren't `n` unconsumed elements prior to the
523    /// cursor, an error will be returned instead. In case of an error, the cursor will stay at the position
524    /// it pointed at prior to calling this method.
525    ///
526    /// If you want to reset the cursor to the first unconsumed element even if there aren't `n`
527    /// unconsumed elements before the cursor position, the [`move_backward_or_reset`] method can be
528    /// used.
529    ///
530    /// [`move_backward_or_reset`]: struct.PeekMoreIterator.html#method.move_backward_or_reset
531    #[inline]
532    pub fn move_cursor_back_by(
533        &mut self,
534        n: usize,
535    ) -> Result<&mut PeekMoreIterator<I>, PeekMoreError> {
536        if self.cursor < n {
537            Err(PeekMoreError::ElementHasBeenConsumed)
538        } else {
539            self.cursor -= n;
540            Ok(self)
541        }
542    }
543
544    /// Move the cursor `n` elements backward, or reset its position to the first non-consumed element.
545    /// The latter happens when the cursor position is smaller than the elements it has to move
546    /// backwards by.
547    #[inline]
548    pub fn move_cursor_back_or_reset(&mut self, n: usize) -> &mut PeekMoreIterator<I> {
549        if self.cursor < n {
550            self.reset_cursor();
551        } else {
552            self.cursor -= n;
553        }
554
555        self
556    }
557
558    /// Move the cursor to the n-th element of the queue.
559    #[inline]
560    pub fn move_nth(&mut self, n: usize) -> &mut PeekMoreIterator<I> {
561        self.cursor = n;
562        self
563    }
564
565    /// Deprecated: use [`reset_cursor`] instead.
566    ///
567    /// [`reset_cursor`]: struct.PeekMoreIterator.html#method.reset_cursor
568    #[deprecated]
569    #[inline]
570    pub fn reset_view(&mut self) {
571        self.reset_cursor()
572    }
573
574    /// Reset the position of the cursor.
575    ///
576    /// If [`peek`] is called just after a reset, it will return a reference to the first element.
577    ///
578    /// [`peek`]: struct.PeekMoreIterator.html#method.peek
579    #[inline]
580    pub fn reset_cursor(&mut self) {
581        self.cursor = 0;
582    }
583
584    /// Return the current cursor position.
585    /// This is intended for use by code that more finely controls where the iterator resets to.
586    #[inline]
587    pub fn cursor(&self) -> usize {
588        self.cursor
589    }
590
591    /// Fills the queue up to (including) the cursor.
592    #[inline]
593    fn fill_queue(&mut self, required_elements: usize) {
594        let stored_elements = self.queue.len();
595
596        if stored_elements <= required_elements {
597            for _ in stored_elements..=required_elements {
598                self.push_next_to_queue()
599            }
600        }
601    }
602
603    /// Consume the underlying iterator and push an element to the queue.
604    #[inline]
605    fn push_next_to_queue(&mut self) {
606        let item = self.iterator.next();
607        self.queue.push(item);
608    }
609
610    /// Increment the cursor which points to the current peekable item.
611    /// Note: if the cursor is [core::usize::MAX], it will not increment any further.
612    ///
613    /// [core::usize::MAX]: https://doc.rust-lang.org/core/usize/constant.MAX.html
614    #[inline]
615    fn increment_cursor(&mut self) {
616        // do not overflow
617        self.cursor = self.cursor.saturating_add(1);
618    }
619
620    /// Decrement the cursor which points to the current peekable item.
621    /// Note: if the cursor is [core::usize::MIN], it will not decrement any further.
622    ///
623    /// [core::usize::MIN]: https://doc.rust-lang.org/core/usize/constant.MIN.html
624    #[inline]
625    fn decrement_cursor(&mut self) {
626        if self.cursor > core::usize::MIN {
627            self.cursor -= 1;
628        }
629    }
630
631    /// Remove all elements from the start of the iterator until reaching the same
632    /// position as the cursor by calling `Iterator::next()`.
633    ///
634    /// After calling this method, `iter.peek() == iter.next().as_ref()`.
635    ///
636    ///```rust
637    /// use peekmore::PeekMore;
638    ///
639    /// let iterable = [1, 2, 3, 4];
640    /// let mut iter = iterable.iter().peekmore();
641    ///
642    /// iter.advance_cursor_by(2);
643    /// assert_eq!(iter.peek(), Some(&&3));
644    /// assert_eq!(iter.next(), Some(&1));
645    /// iter.truncate_iterator_to_cursor();
646    /// assert_eq!(iter.peek(), Some(&&3));
647    /// assert_eq!(iter.next(), Some(&3));
648    ///```
649    pub fn truncate_iterator_to_cursor(&mut self) {
650        if self.cursor < self.queue.len() {
651            self.queue.drain(0..self.cursor);
652        } else {
653            // if the cursor is greater than the queue length,
654            // we want to remove the overflow from the iterator
655            for _ in 0..self.cursor.saturating_sub(self.queue.len()) {
656                let _ = self.iterator.next();
657            }
658            self.queue.clear();
659        }
660
661        self.cursor = 0;
662    }
663
664    /// Returns a view into the next `start` (inclusive) to `end` (exclusive) elements.
665    ///
666    /// **Note:** `start` and `end` represent indices and start at `0`. These indices always start
667    /// at the beginning of the queue (the unconsumed iterator) and don't take the position of the cursor
668    /// into account.
669    ///
670    /// # Panics
671    ///
672    /// **Panics** if `start > end`, in which case the range would be negative.
673    ///
674    /// ```
675    /// use peekmore::PeekMore;
676    ///
677    /// let iterable = [1, 2, 3, 4];
678    /// let mut iter = iterable.iter().peekmore();
679    ///
680    /// match iter.peek_range(1, 3) {
681    ///     [Some(2), Some(p)] => println!("Yay! we found number {} after number 2", p),
682    ///     _ => println!("Oh noes!"),
683    /// }
684    /// ```
685    // implementation choice:
686    // why not `core::ops::RangeBound<T>`? it adds unnecessary complexity since we would need to define what
687    // unbounded bounds mean (e.g. for end whether it would be the end of the queue or the unconsumed iterator
688    // elements until None or that it won't be allowed, or some other definition), we would need to map
689    // the range Inclusive and Exclusive and Unbound-ed elements to usize, and we would need to verify
690    // that T would be an unsigned integer. Using RangeBound would not be all negative though since we
691    // could then use the standard Rust range syntax options such as 0..4 or 0..=3, which clearly
692    // tell a user what kind of bounds are used (inclusive, exclusive, etc.)
693    // For now however, for the reason of not adding unnecessary complexity, I've decided
694    // that the simplicity of concrete start and end types is the better choice.
695    pub fn peek_range(&mut self, start: usize, end: usize) -> &[Option<I::Item>] {
696        assert!(
697            start <= end,
698            "range of the peeked view [start, end] should be positive (i.e. start <= end)"
699        );
700
701        // fill the queue if we don't have enough elements
702        if end > self.queue.len() {
703            self.fill_queue(end);
704        }
705
706        // return a view of the selected range
707
708        &self.queue.as_slice()[start..end]
709    }
710
711    /// Returns a view into the next `n` unconsumed elements of the iterator.
712    ///
713    /// Here, `n` represents the amount of elements as counted from the start of the unconsumed iterator.
714    ///
715    /// For example, if we created a (peekmore) iterator from the array `[1, 2, 3]` and consume the first
716    /// element by calling the regular `Iterator::next` method, and then call `peek_amount(3)`, the iterator will
717    /// return `&[Some(2), Some(3), None]`. Here `Some(2)` and `Some(3)` are queued elements which
718    /// we can peek at, and are not consumed by the iterator yet. `None` is the last element returned by
719    /// our view, since our original iterator is sized and doesn't contain more elements. Thus in the absence
720    /// of additional elements, we return `None`. This method is a variation on [`peek_range`].
721    /// You could instead have called `peek_range(0, n)` (note that `peek_range` takes indices as arguments
722    /// instead of an amount).
723    ///
724    /// **Note:** This method does not use or modify the position of the cursor.
725    ///
726    /// # Example:
727    ///
728    /// ```
729    /// use peekmore::PeekMore;
730    ///
731    /// let iterable = [1, 2, 3];
732    /// let mut iter = iterable.iter().peekmore();
733    ///
734    /// match iter.peek_amount(4) { // -> &[Option(&1), Option(&2), Option(&3), None]
735    ///   [Some(a), Some(b), Some(c), None] => println!("Found a match ({}, {}, {}) ", a, b, c),
736    ///   _ => eprintln!("Expected (just) 3 more values"),
737    /// }
738    /// ```
739    ///
740    /// [`peek_range`]: struct.PeekMoreIterator.html#method.peek_range
741    #[inline]
742    pub fn peek_amount(&mut self, n: usize) -> &[Option<I::Item>] {
743        self.peek_range(0, n)
744    }
745
746    /// Consumes and returns the next item of this iterator if a condition is true.
747    ///
748    /// If `func` returns `true` for the next item of this iterator, consume and return it.
749    /// Otherwise, return `None`.
750    ///
751    /// Note: This function always uses the next item of the iterator and it is independent of
752    /// the cursor location.
753    ///
754    /// # Example:
755    /// Consume items one-by-one.
756    /// ```
757    /// use peekmore::PeekMore;
758    ///
759    /// let mut iter = (1..5).peekmore();
760    ///
761    /// assert_eq!(iter.next_if(|&x| x == 1), Some(1));
762    ///
763    /// // next_eq does not care about the cursor position
764    /// let mut iter = iter.advance_cursor();
765    /// assert_eq!(iter.peek(), Some(&3));
766    /// assert_eq!(iter.next_if(|&x| x == 2), Some(2));
767    /// ```
768    /// Consume a range of items.
769    /// ```
770    /// use peekmore::PeekMore;
771    ///
772    /// let mut iter = (1..15).peekmore();
773    ///
774    /// while iter.next_if(|&x| x <= 10).is_some() {}
775    /// assert_eq!(iter.next(), Some(11));
776    /// ```
777    #[inline]
778    pub fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item> {
779        match self.peek_first() {
780            Some(matched) if func(matched) => self.next(),
781            _ => None,
782        }
783    }
784
785    /// Consumes and returns the next item if it is equal to `expected`.
786    ///
787    /// Uses [`next_eq`] underneath.
788    ///
789    /// [`next_eq`]: struct.PeekMoreIterator.html#method.next_if
790    #[inline]
791    pub fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
792    where
793        T: ?Sized,
794        I::Item: PartialEq<T>,
795    {
796        self.next_if(|next| next == expected)
797    }
798}
799
800impl<I: Iterator> Iterator for PeekMoreIterator<I> {
801    type Item = I::Item;
802
803    fn next(&mut self) -> Option<Self::Item> {
804        let res = if self.queue.is_empty() {
805            self.iterator.next()
806        } else {
807            self.queue.remove(0)
808        };
809
810        self.decrement_cursor();
811
812        res
813    }
814}
815
816/// Uses [`ExactSizeIterator`] default implementation.
817///
818/// [`ExactSizeIterator`]: https://doc.rust-lang.org/core/iter/trait.ExactSizeIterator.html
819impl<I: ExactSizeIterator> ExactSizeIterator for PeekMoreIterator<I> {}
820
821/// Uses [`FusedIterator`] default implementation.
822///
823/// [`FusedIterator`]: https://doc.rust-lang.org/core/iter/trait.FusedIterator.html
824impl<I: FusedIterator> FusedIterator for PeekMoreIterator<I> {}
825
826/// This enumeration provides errors which represent lack of success of the [`PeekMoreIterator`].
827///
828/// [`PeekMoreIterator`]: struct.PeekMoreIterator.html
829#[derive(Debug, Eq, PartialEq)]
830pub enum PeekMoreError {
831    /// This error case will be returned if we try to move to an element, but it has already been
832    /// consumed by the iterator.
833    /// We can only peek at elements which haven't been consumed.
834    ElementHasBeenConsumed,
835}
836
837#[cfg(test)]
838mod tests {
839    use super::*;
840
841    #[test]
842    fn readme_example() {
843        let range10 = 0..11;
844        let mut peekable = range10.peekmore();
845
846        // Peek at the first element
847        let peek_first = peekable.peek();
848        assert_eq!(*peek_first.unwrap(), 0);
849
850        let peek_first_redux = peekable.peek_nth(0);
851        assert_eq!(*peek_first_redux.unwrap(), 0);
852
853        // Peek at the 10th (index) element
854        let peek_tenth = peekable.peek_nth(10);
855        assert_eq!(*peek_tenth.unwrap(), 10);
856
857        // Consume the 10th element
858        let tenth = peekable.nth(10);
859        assert_eq!(tenth.unwrap(), 10);
860
861        // Show that there are no more elements
862        assert_eq!(peekable.peek(), None);
863        assert_eq!(peekable.next(), None);
864    }
865
866    #[test]
867    fn peek_forward_with_reassignment() {
868        let iterable = [1, 2, 3, 4];
869
870        let mut peek = iterable.iter().peekmore();
871
872        assert_eq!(peek.peek(), Some(&&1));
873
874        let peek = peek.advance_cursor();
875        assert_eq!(peek.peek(), Some(&&2));
876
877        let peek = peek.advance_cursor();
878        assert_eq!(peek.peek(), Some(&&3));
879
880        let peek = peek.advance_cursor();
881        assert_eq!(peek.peek(), Some(&&4));
882
883        let peek = peek.advance_cursor();
884        assert_eq!(peek.peek(), None);
885    }
886
887    #[test]
888    fn peek_forward_without_reassignment_separately_advance_and_peek() {
889        let iterable = [1, 2, 3, 4];
890
891        let mut iter = iterable.iter().peekmore();
892
893        assert_eq!(iter.peek(), Some(&&1));
894
895        let v2 = iter.advance_cursor().peek();
896        assert_eq!(v2, Some(&&2));
897
898        let v3 = iter.advance_cursor().peek();
899        assert_eq!(v3, Some(&&3));
900
901        let v4 = iter.advance_cursor().peek();
902        assert_eq!(v4, Some(&&4));
903
904        let v5 = iter.advance_cursor().peek();
905        assert_eq!(v5, None);
906    }
907
908    #[test]
909    fn peek_forward_without_reassignment_advance_and_peek_combined() {
910        let iterable = [1, 2, 3, 4];
911
912        let mut iter = iterable.iter().peekmore();
913
914        let v1 = iter.peek();
915        assert_eq!(v1, Some(&&1));
916
917        let v2 = iter.peek_next();
918        assert_eq!(v2, Some(&&2));
919
920        let v3 = iter.peek_next();
921        assert_eq!(v3, Some(&&3));
922
923        let v4 = iter.peek_next();
924        assert_eq!(v4, Some(&&4));
925
926        let v5 = iter.peek_next();
927        assert_eq!(v5, None);
928    }
929
930    #[test]
931    fn peek_forward_without_reassignment_advance_and_peek_combined_and_reset_view() {
932        let iterable = [1, 2, 3, 4];
933
934        let mut iter = iterable.iter().peekmore();
935
936        let v1 = iter.peek();
937        assert_eq!(v1, Some(&&1));
938
939        let v2 = iter.peek_next();
940        assert_eq!(v2, Some(&&2));
941
942        iter.reset_cursor();
943        let v1again = iter.peek();
944        assert_eq!(v1again, Some(&&1));
945
946        let v2again = iter.peek_next();
947        assert_eq!(v2again, Some(&&2));
948
949        let v3 = iter.peek_next();
950        assert_eq!(v3, Some(&&3));
951
952        let v4 = iter.peek_next();
953        assert_eq!(v4, Some(&&4));
954
955        let v5 = iter.peek_next();
956        assert_eq!(v5, None);
957    }
958
959    #[test]
960    fn empty() {
961        let iterable: [i32; 0] = [];
962
963        let mut iter = iterable.iter().peekmore();
964
965        assert_eq!(iter.peek(), None);
966
967        let none = iter.peek_next();
968        assert_eq!(none, None);
969
970        let iter = iter.advance_cursor();
971        assert_eq!(iter.peek(), None);
972        assert_eq!(iter.peek_next(), None);
973    }
974
975    #[test]
976    fn test_with_consume() {
977        let iterable = "123".chars();
978
979        let mut iter = iterable.peekmore();
980        assert_eq!(iter.peek(), Some(&core::char::from_digit(1, 10).unwrap()));
981        assert_eq!(
982            iter.peek_next(),
983            Some(&core::char::from_digit(2, 10).unwrap())
984        );
985        assert_eq!(
986            iter.peek_next(),
987            Some(&core::char::from_digit(3, 10).unwrap())
988        );
989        assert_eq!(iter.peek_next(), None);
990        assert_eq!(iter.next(), Some(core::char::from_digit(1, 10).unwrap()));
991        assert_eq!(iter.peek(), None);
992        assert_eq!(iter.peek_next(), None);
993        assert_eq!(iter.next(), Some(core::char::from_digit(2, 10).unwrap()));
994        assert_eq!(iter.peek(), None);
995        assert_eq!(iter.peek_next(), None);
996        assert_eq!(iter.next(), Some(core::char::from_digit(3, 10).unwrap()));
997        assert_eq!(iter.next(), None);
998        assert_eq!(iter.peek_next(), None);
999    }
1000
1001    #[test]
1002    fn test_with_consume_and_reset() {
1003        let iterable = "456".chars();
1004
1005        let mut iter = iterable.peekmore();
1006        assert_eq!(iter.peek(), Some(&core::char::from_digit(4, 10).unwrap()));
1007        assert_eq!(
1008            iter.peek_next(),
1009            Some(&core::char::from_digit(5, 10).unwrap())
1010        );
1011        assert_eq!(
1012            iter.peek_next(),
1013            Some(&core::char::from_digit(6, 10).unwrap())
1014        );
1015        assert_eq!(iter.peek_next(), None);
1016        assert_eq!(iter.next(), Some(core::char::from_digit(4, 10).unwrap()));
1017        iter.reset_cursor();
1018
1019        assert_eq!(iter.peek(), Some(&core::char::from_digit(5, 10).unwrap()));
1020        assert_eq!(
1021            iter.peek_next(),
1022            Some(&core::char::from_digit(6, 10).unwrap())
1023        );
1024
1025        assert_eq!(iter.next(), Some(core::char::from_digit(5, 10).unwrap()));
1026        assert_eq!(iter.next(), Some(core::char::from_digit(6, 10).unwrap()));
1027        assert_eq!(iter.next(), None);
1028        assert_eq!(iter.peek_next(), None);
1029    }
1030
1031    #[test]
1032    fn check_peek_window_moves_with_consume() {
1033        let iterable = [1, 2, 3, 4];
1034
1035        let mut iter = iterable.iter().peekmore();
1036
1037        let v1 = iter.peek();
1038        assert_eq!(v1, Some(&&1));
1039
1040        let v1c = iter.next();
1041        assert_eq!(v1c, Some(&1));
1042
1043        let v2 = iter.peek();
1044        assert_eq!(v2, Some(&&2));
1045
1046        let v2c = iter.next();
1047        assert_eq!(v2c, Some(&2));
1048
1049        let v3 = iter.peek();
1050        assert_eq!(v3, Some(&&3));
1051
1052        iter.reset_cursor();
1053
1054        let v3 = iter.peek();
1055        assert_eq!(v3, Some(&&3));
1056
1057        let v3c = iter.next();
1058        assert_eq!(v3c, Some(&3));
1059
1060        let v4c = iter.next();
1061        assert_eq!(v4c, Some(&4));
1062
1063        let v5 = iter.peek();
1064        assert_eq!(v5, None);
1065
1066        let v5c = iter.next();
1067        assert_eq!(v5c, None);
1068    }
1069
1070    #[test]
1071    fn check_advance_separately() {
1072        let iterable = [1, 2, 3, 4];
1073
1074        let mut iter = iterable.iter().peekmore(); // j -> 1
1075
1076        assert_eq!(iter.cursor(), 0);
1077        assert_eq!(iter.peek(), Some(&&1));
1078
1079        iter.advance_cursor(); // j -> 2
1080        assert_eq!(iter.cursor(), 1);
1081
1082        iter.advance_cursor(); // j -> 3
1083        assert_eq!(iter.cursor(), 2);
1084
1085        iter.advance_cursor(); // j -> 4
1086        assert_eq!(iter.cursor(), 3);
1087
1088        let v4 = iter.peek();
1089        assert_eq!(v4, Some(&&4));
1090    }
1091
1092    #[test]
1093    fn check_advance_chain() {
1094        let iterable = [1, 2, 3, 4];
1095
1096        let mut iter = iterable.iter().peekmore(); // j -> 1
1097
1098        assert_eq!(iter.cursor(), 0);
1099
1100        iter.advance_cursor() // j -> 2
1101            .advance_cursor() // j -> 3
1102            .advance_cursor(); // j -> 4
1103
1104        let v4 = iter.peek();
1105        assert_eq!(v4, Some(&&4));
1106    }
1107
1108    #[test]
1109    fn check_move_previous() {
1110        let iterable = [1, 2, 3, 4];
1111
1112        let mut iter = iterable.iter().peekmore(); // j -> 1
1113
1114        assert_eq!(iter.cursor(), 0);
1115        assert_eq!(iter.peek(), Some(&&1));
1116
1117        iter.advance_cursor(); // j -> 2
1118        assert_eq!(iter.cursor(), 1);
1119
1120        let _ = iter.move_cursor_back(); // j -> 1
1121        assert_eq!(iter.cursor(), 0);
1122
1123        iter.advance_cursor(); // j -> 2
1124        assert_eq!(iter.cursor(), 1);
1125
1126        let _ = iter.move_cursor_back(); // j -> 1
1127        assert_eq!(iter.cursor(), 0);
1128
1129        iter.advance_cursor(); // j -> 2
1130        assert_eq!(iter.cursor(), 1);
1131
1132        iter.advance_cursor() // j -> 3
1133            .advance_cursor(); // j -> 4
1134
1135        assert_eq!(iter.cursor(), 3);
1136
1137        let v4 = iter.peek();
1138        assert_eq!(v4, Some(&&4));
1139
1140        let _ = iter.move_cursor_back().and_then(|it| {
1141            it.move_cursor_back() // j -> 3
1142                .and_then(|it| {
1143                    it.move_cursor_back() // j -> 2
1144                        .and_then(|it| it.move_cursor_back())
1145                })
1146        }); // j -> 1
1147
1148        let v1 = iter.peek();
1149        assert_eq!(v1, Some(&&1));
1150
1151        let prev = iter.move_cursor_back();
1152        assert!(prev.is_err());
1153
1154        let v1 = iter.peek();
1155        assert_eq!(v1, Some(&&1));
1156    }
1157
1158    #[test]
1159    fn test_with_inherited_feature_count() {
1160        let iterable = [1, 2, 3];
1161        let mut iter = iterable.iter().peekmore();
1162
1163        iter.advance_cursor();
1164        let second = iter.peek().unwrap();
1165        assert_eq!(second, &&2);
1166
1167        let consume_first = iter.next().unwrap();
1168        assert_eq!(consume_first, &1);
1169
1170        let count = iter.count();
1171        assert_eq!(count, 2);
1172    }
1173
1174    #[test]
1175    fn peek_previous() {
1176        let iterable = [1, 2, 3];
1177        let mut iter = iterable.iter().peekmore(); // j = 1
1178
1179        iter.advance_cursor(); // j = 2
1180        iter.advance_cursor(); // j = 3
1181        let value = iter.peek().unwrap(); // 3
1182        assert_eq!(value, &&3);
1183
1184        let peek = iter.peek_previous(); // 2
1185        assert_eq!(peek.unwrap(), Some(&&2));
1186        assert_eq!(iter.cursor(), 1);
1187
1188        let peek = iter.peek_previous(); // 1
1189        assert_eq!(peek.unwrap(), Some(&&1));
1190        assert_eq!(iter.cursor(), 0);
1191
1192        let peek = iter.peek_previous();
1193        assert_eq!(peek, Err(PeekMoreError::ElementHasBeenConsumed));
1194        assert_eq!(iter.cursor(), 0);
1195    }
1196
1197    #[test]
1198    fn peek_previous_beyond_none() {
1199        let iterable = [1];
1200        let mut iter = iterable.iter().peekmore(); // j = 1
1201        assert_eq!(iter.cursor(), 0);
1202
1203        iter.advance_cursor(); // j = None (1)
1204        let peek = iter.peek();
1205        assert_eq!(peek, None);
1206        assert_eq!(iter.cursor(), 1);
1207
1208        iter.advance_cursor(); // j = None (2)
1209        let peek = iter.peek();
1210        assert_eq!(peek, None);
1211        assert_eq!(iter.cursor(), 2);
1212
1213        iter.advance_cursor(); // j = None (3)
1214        let peek = iter.peek(); // current
1215        assert_eq!(peek, None);
1216        assert_eq!(iter.cursor(), 3);
1217
1218        let peek = iter.peek_previous(); // None (2)
1219        assert_eq!(peek.unwrap(), None);
1220        assert_eq!(iter.cursor(), 2);
1221
1222        let peek = iter.peek_previous(); // None (1)
1223        assert_eq!(peek.unwrap(), None);
1224        assert_eq!(iter.cursor(), 1);
1225
1226        let peek = iter.peek_previous(); // 1
1227        assert_eq!(peek.unwrap(), Some(&&1));
1228        assert_eq!(iter.cursor(), 0);
1229
1230        let peek = iter.peek_previous();
1231        assert_eq!(peek, Err(PeekMoreError::ElementHasBeenConsumed));
1232        assert_eq!(iter.cursor(), 0);
1233
1234        let peek = iter.peek_previous();
1235        assert_eq!(peek, Err(PeekMoreError::ElementHasBeenConsumed));
1236        assert_eq!(iter.cursor(), 0);
1237    }
1238
1239    #[test]
1240    fn check_move_forward() {
1241        let iterable = [1, 2, 3, 4];
1242        let mut iter = iterable.iter().peekmore();
1243
1244        let _ = iter.advance_cursor_by(3);
1245
1246        let peek = iter.peek();
1247        assert_eq!(peek, Some(&&4));
1248        assert_eq!(iter.cursor(), 3);
1249
1250        let _ = iter.advance_cursor_by(3);
1251        let peek = iter.peek();
1252        assert_eq!(peek, None);
1253        assert_eq!(iter.cursor(), 6);
1254    }
1255
1256    #[test]
1257    fn check_move_backward() {
1258        let iterable = [1, 2, 3, 4];
1259        let mut iter = iterable.iter().peekmore();
1260
1261        let _ = iter.advance_cursor_by(3);
1262
1263        let peek = iter.peek();
1264        assert_eq!(peek, Some(&&4));
1265        assert_eq!(iter.cursor(), 3);
1266
1267        let result = iter.move_cursor_back_by(2);
1268        assert!(result.is_ok());
1269        let peek = iter.peek();
1270        assert_eq!(peek, Some(&&2));
1271        assert_eq!(iter.cursor(), 1);
1272
1273        let result = iter.move_cursor_back_by(1);
1274        assert!(result.is_ok());
1275        let peek = iter.peek();
1276        assert_eq!(peek, Some(&&1));
1277        assert_eq!(iter.cursor(), 0);
1278
1279        let result = iter.move_cursor_back_by(1);
1280        assert!(result.is_err());
1281        let peek = iter.peek();
1282        assert_eq!(peek, Some(&&1));
1283        assert_eq!(iter.cursor(), 0);
1284    }
1285
1286    #[test]
1287    fn check_move_backward_beyond_consumed_verify_cursor_position() {
1288        let iterable = [1, 2, 3, 4];
1289        let mut iter = iterable.iter().peekmore();
1290
1291        let _ = iter.advance_cursor_by(3);
1292
1293        let peek = iter.peek();
1294        assert_eq!(peek, Some(&&4));
1295        assert_eq!(iter.cursor(), 3);
1296
1297        let result = iter.move_cursor_back_by(5);
1298        assert!(result.is_err());
1299        let peek = iter.peek();
1300        assert_eq!(peek, Some(&&4));
1301        assert_eq!(iter.cursor(), 3);
1302    }
1303
1304    #[test]
1305    fn check_move_backward_or_reset() {
1306        let iterable = [1, 2, 3, 4];
1307        let mut iter = iterable.iter().peekmore();
1308
1309        let _ = iter.advance_cursor_by(3);
1310
1311        let peek = iter.peek();
1312        assert_eq!(peek, Some(&&4));
1313        assert_eq!(iter.cursor(), 3);
1314
1315        let _ = iter.move_cursor_back_or_reset(2);
1316        let peek = iter.peek();
1317        assert_eq!(peek, Some(&&2));
1318        assert_eq!(iter.cursor(), 1);
1319
1320        let _ = iter.move_cursor_back_or_reset(1);
1321        let peek = iter.peek();
1322        assert_eq!(peek, Some(&&1));
1323        assert_eq!(iter.cursor(), 0);
1324
1325        let _ = iter.move_cursor_back_or_reset(1);
1326        let peek = iter.peek();
1327        assert_eq!(peek, Some(&&1));
1328        assert_eq!(iter.cursor(), 0);
1329    }
1330
1331    #[test]
1332    fn check_move_backward_or_reset_beyond_consumed_verify_cursor_position() {
1333        let iterable = [1, 2, 3, 4];
1334        let mut iter = iterable.iter().peekmore();
1335
1336        let _ = iter.advance_cursor_by(3);
1337
1338        let peek = iter.peek();
1339        assert_eq!(peek, Some(&&4));
1340        assert_eq!(iter.cursor(), 3);
1341
1342        let _ = iter.move_cursor_back_or_reset(5);
1343        let peek = iter.peek();
1344        assert_eq!(peek, Some(&&1));
1345        assert_eq!(iter.cursor(), 0);
1346    }
1347
1348    #[test]
1349    fn check_move_backward_or_reset_empty() {
1350        let iterable = "".chars();
1351
1352        let mut iter = iterable.peekmore();
1353
1354        assert_eq!(iter.peek(), None);
1355        assert_eq!(iter.cursor(), 0);
1356
1357        let _ = iter.move_cursor_back_or_reset(5);
1358
1359        assert_eq!(iter.peek(), None);
1360        assert_eq!(iter.cursor(), 0);
1361    }
1362
1363    #[test]
1364    fn check_peek_forward() {
1365        let iterable = [1, 2, 3, 4];
1366        let mut iter = iterable.iter().peekmore();
1367
1368        let peek = iter.peek_forward(3);
1369
1370        assert_eq!(peek, Some(&&4));
1371        assert_eq!(iter.cursor(), 3);
1372
1373        let peek = iter.peek_forward(3);
1374        assert_eq!(peek, None);
1375        assert_eq!(iter.cursor(), 6);
1376    }
1377
1378    #[test]
1379    fn check_peek_backward() {
1380        let iterable = [1, 2, 3, 4];
1381        let mut iter = iterable.iter().peekmore();
1382
1383        let _ = iter.advance_cursor_by(3);
1384
1385        let peek = iter.peek();
1386        assert_eq!(peek, Some(&&4));
1387        assert_eq!(iter.cursor(), 3);
1388
1389        let result = iter.peek_backward(2);
1390        assert!(result.is_ok());
1391        assert_eq!(result.unwrap(), Some(&&2));
1392        assert_eq!(iter.cursor(), 1);
1393
1394        let result = iter.peek_backward(1);
1395        assert!(result.is_ok());
1396        assert_eq!(result.unwrap(), Some(&&1));
1397        assert_eq!(iter.cursor(), 0);
1398
1399        let result = iter.peek_backward(1);
1400        assert!(result.is_err());
1401        let peek = iter.peek();
1402        assert_eq!(peek, Some(&&1));
1403        assert_eq!(iter.cursor(), 0);
1404    }
1405
1406    #[test]
1407    fn check_peek_backward_beyond_consumed_verify_cursor_position() {
1408        let iterable = [1, 2, 3, 4];
1409        let mut iter = iterable.iter().peekmore();
1410
1411        let _ = iter.advance_cursor_by(3);
1412
1413        let peek = iter.peek();
1414        assert_eq!(peek, Some(&&4));
1415        assert_eq!(iter.cursor(), 3);
1416
1417        let result = iter.peek_backward(5);
1418        assert!(result.is_err());
1419        let peek = iter.peek();
1420        assert_eq!(peek, Some(&&4));
1421        assert_eq!(iter.cursor(), 3);
1422    }
1423
1424    #[test]
1425    fn check_peek_backward_or_first_beyond_consumed_verify_cursor_position() {
1426        let iterable = [1, 2, 3, 4];
1427        let mut iter = iterable.iter().peekmore();
1428
1429        let _ = iter.advance_cursor_by(3);
1430
1431        let peek = iter.peek();
1432        assert_eq!(peek, Some(&&4));
1433        assert_eq!(iter.cursor(), 3);
1434
1435        let peek = iter.peek_backward_or_first(5);
1436        assert_eq!(peek, Some(&&1));
1437        assert_eq!(iter.cursor(), 0);
1438    }
1439
1440    #[test]
1441    fn check_peek_backward_or_first_empty() {
1442        let iterable = "".chars();
1443
1444        let mut iter = iterable.peekmore();
1445
1446        assert_eq!(iter.peek(), None);
1447        assert_eq!(iter.cursor(), 0);
1448
1449        let peek = iter.peek_backward_or_first(5);
1450
1451        assert_eq!(peek, None);
1452        assert_eq!(iter.cursor(), 0);
1453    }
1454
1455    #[test]
1456    fn check_move_forward_while() {
1457        let iterable = [1, 2, 3, 4];
1458        let mut iter = iterable.iter().peekmore();
1459
1460        let _ = iter.advance_cursor_while(|i| **i.unwrap() != 3);
1461
1462        let peek = iter.peek();
1463        assert_eq!(peek, Some(&&3));
1464        assert_eq!(iter.cursor(), 2);
1465    }
1466
1467    #[test]
1468    fn check_move_forward_while_empty() {
1469        let iterable: [i32; 0] = [];
1470        let mut iter = iterable.iter().peekmore();
1471
1472        let _ = iter.advance_cursor_while(|i| if let Some(i) = i { **i != 3 } else { false });
1473
1474        let peek = iter.peek();
1475        assert_eq!(peek, None);
1476        assert_eq!(iter.cursor(), 0);
1477    }
1478
1479    #[test]
1480    fn check_move_forward_while_some() {
1481        let iterable = [1, 2, 3, 4];
1482        let mut iter = iterable.iter().peekmore();
1483
1484        let _ = iter.advance_cursor_while(|i| i.is_some());
1485
1486        let peek = iter.peek();
1487        assert_eq!(peek, None);
1488        assert_eq!(iter.cursor(), 4);
1489    }
1490
1491    #[test]
1492    fn check_move_forward_while_fast_fail() {
1493        let iterable = [1, 2, 3, 4];
1494        let mut iter = iterable.iter().peekmore();
1495
1496        iter.advance_cursor_by(2);
1497
1498        let _ = iter.advance_cursor_while(|i| **i.unwrap() > 3);
1499
1500        let peek = iter.peek();
1501        assert_eq!(peek, Some(&&3));
1502        assert_eq!(iter.cursor(), 2);
1503    }
1504
1505    #[test]
1506    fn check_peek_nth() {
1507        let iterable = [1, 2, 3, 4];
1508
1509        let mut iter = iterable.iter().peekmore();
1510
1511        assert_eq!(iter.peek_nth(0), Some(&&1));
1512        assert_eq!(iter.cursor(), 0);
1513        assert_eq!(iter.peek_nth(1), Some(&&2));
1514        assert_eq!(iter.cursor(), 0);
1515        assert_eq!(iter.peek_nth(2), Some(&&3));
1516        assert_eq!(iter.cursor(), 0);
1517        assert_eq!(iter.peek_nth(3), Some(&&4));
1518        assert_eq!(iter.cursor(), 0);
1519        assert_eq!(iter.peek_nth(4), None);
1520        assert_eq!(iter.cursor(), 0);
1521    }
1522
1523    #[test]
1524    fn check_peek_first() {
1525        let iterable = [1, 2, 3, 4];
1526        let mut iter = iterable.iter().peekmore();
1527
1528        // testing to make sure no matter where the cursor is, we always point
1529        // to the initial first element.
1530        assert_eq!(iter.peek_first(), Some(&&1));
1531        assert_eq!(iter.cursor(), 0);
1532        iter.increment_cursor();
1533        assert_eq!(iter.peek_first(), Some(&&1));
1534        assert_eq!(iter.cursor(), 1);
1535        iter.increment_cursor();
1536        assert_eq!(iter.peek_first(), Some(&&1));
1537        assert_eq!(iter.cursor(), 2);
1538        iter.increment_cursor();
1539        assert_eq!(iter.peek_first(), Some(&&1));
1540        assert_eq!(iter.cursor(), 3);
1541        iter.increment_cursor(); // try moving past the end too
1542        assert_eq!(iter.peek_first(), Some(&&1));
1543
1544        // testing to ensure that it's the first *unconsumed* element of the iterator
1545        // and not the first of the iterable.
1546        iter.next();
1547        assert_eq!(iter.peek_first(), Some(&&2));
1548        iter.increment_cursor();
1549        assert_eq!(iter.peek_first(), Some(&&2));
1550
1551        // testing at the end boundary of the iterable.
1552        iter.next(); // consume 2
1553        iter.next(); // consume 3
1554        assert_eq!(iter.peek_first(), Some(&&4));
1555
1556        // test that if there's no unconsumed elements, it reports None.
1557        iter.next();
1558        assert_eq!(iter.peek_first(), None);
1559    }
1560
1561    #[test]
1562    fn check_peek_nth_empty() {
1563        let iterable: [i32; 0] = [];
1564
1565        let mut iter = iterable.iter().peekmore();
1566
1567        assert_eq!(iter.peek_nth(0), None);
1568        assert_eq!(iter.cursor(), 0);
1569        assert_eq!(iter.peek_nth(1), None);
1570        assert_eq!(iter.cursor(), 0);
1571    }
1572
1573    #[test]
1574    fn check_move_nth() {
1575        let iterable = [1, 2, 3, 4];
1576
1577        let mut iter = iterable.iter().peekmore();
1578
1579        iter.move_nth(20);
1580        assert_eq!(iter.peek_nth(0), Some(&&1));
1581        assert_eq!(iter.cursor(), 20);
1582        assert_eq!(iter.peek(), None);
1583
1584        iter.move_nth(0);
1585        assert_eq!(iter.peek(), Some(&&1));
1586
1587        iter.move_nth(3);
1588        assert_eq!(iter.peek(), Some(&&4));
1589    }
1590
1591    #[test]
1592    fn check_move_nth_empty() {
1593        let iterable: [i32; 0] = [];
1594
1595        let mut iter = iterable.iter().peekmore();
1596
1597        iter.move_nth(0);
1598        assert_eq!(iter.cursor(), 0);
1599
1600        iter.move_nth(10);
1601        assert_eq!(iter.cursor(), 10);
1602    }
1603
1604    #[test]
1605    fn truncate_iterator_to_cursor_is_noop_when_queue_is_empty_from_no_peeking() {
1606        let iterable = [1, 2, 3, 4];
1607
1608        let mut iter = iterable.iter().peekmore();
1609
1610        assert!(iter.queue.is_empty());
1611
1612        iter.truncate_iterator_to_cursor();
1613
1614        assert!(iter.queue.is_empty());
1615        assert_eq!(iter.peek(), Some(&&1));
1616        assert!(!iter.queue.is_empty());
1617    }
1618
1619    #[test]
1620    fn truncate_iterator_to_cursor_is_noop_when_queue_is_empty_from_iteration() {
1621        let iterable = [1, 2, 3, 4];
1622
1623        let mut iter = iterable.iter().peekmore();
1624
1625        assert!(iter.queue.is_empty());
1626
1627        iter.peek_forward(2);
1628        iter.next();
1629        iter.next();
1630        iter.next();
1631
1632        assert!(iter.queue.is_empty());
1633
1634        iter.truncate_iterator_to_cursor();
1635
1636        assert!(iter.queue.is_empty());
1637        assert_eq!(iter.peek(), Some(&&4));
1638        assert!(!iter.queue.is_empty());
1639    }
1640
1641    #[test]
1642    fn truncate_to_iterator_fill_queue() {
1643        let mut iter = [0, 1, 2, 3].iter().peekmore();
1644        iter.advance_cursor();
1645        iter.truncate_iterator_to_cursor();
1646
1647        let value = **iter.peek().unwrap();
1648
1649        assert_eq!(value, 1);
1650    }
1651
1652    #[test]
1653    fn truncate_to_iterator_on_empty_collection() {
1654        let mut iter = core::iter::empty::<i32>().peekmore();
1655        iter.advance_cursor();
1656        assert_eq!(iter.cursor, 1);
1657
1658        iter.truncate_iterator_to_cursor();
1659        assert_eq!(iter.cursor, 0);
1660
1661        assert!(iter.peek().is_none());
1662    }
1663
1664    #[test]
1665    fn truncate_to_iterator_on_single_element_collection() {
1666        let mut iter = core::iter::once(0).peekmore();
1667        assert_eq!(*iter.peek().unwrap(), 0);
1668        assert_eq!(iter.cursor, 0);
1669
1670        iter.advance_cursor(); // starts at 0, so now is 1 (i.e. second element so None)
1671        assert_eq!(iter.cursor, 1);
1672        assert!(iter.peek().is_none());
1673
1674        iter.truncate_iterator_to_cursor();
1675        assert_eq!(iter.cursor, 0);
1676
1677        assert!(iter.peek().is_none());
1678    }
1679
1680    #[test]
1681    fn truncate_to_iterator_cursor_and_queue_equal_length() {
1682        let mut iter = [0, 1, 2, 3].iter().peekmore();
1683        iter.peek();
1684        iter.advance_cursor();
1685        iter.truncate_iterator_to_cursor();
1686
1687        assert_eq!(iter.next(), Some(&1));
1688        assert_eq!(iter.next(), Some(&2));
1689        assert_eq!(iter.next(), Some(&3));
1690        assert_eq!(iter.next(), None);
1691    }
1692
1693    #[test]
1694    fn truncate_to_iterator_cursor_less_than_queue_length() {
1695        let mut iter = [0, 1, 2, 3].iter().peekmore();
1696        iter.peek_nth(2);
1697        iter.truncate_iterator_to_cursor();
1698
1699        assert_eq!(iter.next(), Some(&0));
1700        assert_eq!(iter.next(), Some(&1));
1701        assert_eq!(iter.next(), Some(&2));
1702        assert_eq!(iter.next(), Some(&3));
1703        assert_eq!(iter.next(), None);
1704
1705        let mut iter = [0, 1, 2, 3].iter().peekmore();
1706        iter.peek_nth(3);
1707        iter.advance_cursor();
1708        iter.truncate_iterator_to_cursor();
1709
1710        assert_eq!(iter.next(), Some(&1));
1711        assert_eq!(iter.next(), Some(&2));
1712        assert_eq!(iter.next(), Some(&3));
1713        assert_eq!(iter.next(), None);
1714    }
1715
1716    #[test]
1717    fn peek_range_from_start_smaller_than_input_len() {
1718        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1719        let view = peeking_queue.peek_range(0, 2);
1720
1721        assert_eq!(view[0], Some(&0));
1722        assert_eq!(view[1], Some(&1));
1723        assert_eq!(view.len(), 2);
1724    }
1725
1726    #[test]
1727    fn peek_range_from_start_eq_to_input_len() {
1728        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1729        let view = peeking_queue.peek_range(0, 4);
1730
1731        assert_eq!(view[0], Some(&0));
1732        assert_eq!(view[1], Some(&1));
1733        assert_eq!(view[2], Some(&2));
1734        assert_eq!(view[3], Some(&3));
1735        assert_eq!(view.len(), 4);
1736    }
1737
1738    #[test]
1739    fn peek_range_from_start_bigger_than_input_len() {
1740        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1741        let view = peeking_queue.peek_range(0, 6);
1742
1743        assert_eq!(view[0], Some(&0));
1744        assert_eq!(view[1], Some(&1));
1745        assert_eq!(view[2], Some(&2));
1746        assert_eq!(view[3], Some(&3));
1747        assert_eq!(view[4], None);
1748        assert_eq!(view[5], None);
1749        assert_eq!(view.len(), 6);
1750    }
1751
1752    #[test]
1753    fn peek_range_from_middle() {
1754        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1755        let view = peeking_queue.peek_range(2, 5);
1756
1757        assert_eq!(view[0], Some(&2));
1758        assert_eq!(view[1], Some(&3));
1759        assert_eq!(view[2], None);
1760        assert_eq!(view.len(), 3);
1761    }
1762
1763    #[test]
1764    fn peek_range_out_of_bounds() {
1765        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1766        let view = peeking_queue.peek_range(5, 6);
1767
1768        assert_eq!(view[0], None);
1769        assert_eq!(view.len(), 1);
1770    }
1771
1772    #[test]
1773    fn peek_range_empty() {
1774        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1775        let view = peeking_queue.peek_range(0, 0);
1776
1777        assert_eq!(view.len(), 0);
1778    }
1779
1780    #[test]
1781    fn peek_range_match() {
1782        let mut peeking_queue = ["call", "f", "1"].iter().peekmore();
1783        let view = peeking_queue.peek_range(1, 3);
1784
1785        let value = match view {
1786            [Some(&"f"), Some(arg)] => arg,
1787            _ => panic!("test case peek_range_match failed"),
1788        };
1789
1790        assert_eq!(**value, "1");
1791        assert_eq!(view.len(), 2);
1792    }
1793
1794    #[test]
1795    #[should_panic]
1796    fn peek_range_panic_on_invalid_range() {
1797        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1798        let _ = peeking_queue.peek_range(2, 1);
1799    }
1800
1801    #[test]
1802    fn peek_amount_from_start_smaller_than_input_len() {
1803        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1804        let view = peeking_queue.peek_amount(2);
1805
1806        assert_eq!(view[0], Some(&0));
1807        assert_eq!(view[1], Some(&1));
1808        assert_eq!(view.len(), 2);
1809    }
1810
1811    #[test]
1812    fn peek_amount_from_start_eq_to_input_len() {
1813        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1814        let view = peeking_queue.peek_amount(4);
1815
1816        assert_eq!(view[0], Some(&0));
1817        assert_eq!(view[1], Some(&1));
1818        assert_eq!(view[2], Some(&2));
1819        assert_eq!(view[3], Some(&3));
1820        assert_eq!(view.len(), 4);
1821    }
1822
1823    #[test]
1824    fn peek_amount_from_start_bigger_than_input_len() {
1825        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1826        let view = peeking_queue.peek_amount(6);
1827
1828        assert_eq!(view[0], Some(&0));
1829        assert_eq!(view[1], Some(&1));
1830        assert_eq!(view[2], Some(&2));
1831        assert_eq!(view[3], Some(&3));
1832        assert_eq!(view[4], None);
1833        assert_eq!(view[5], None);
1834        assert_eq!(view.len(), 6);
1835    }
1836
1837    #[test]
1838    fn peek_amount_empty() {
1839        let empty: [u32; 0] = [];
1840        let mut peeking_queue = empty.iter().peekmore();
1841        let view = peeking_queue.peek_amount(3);
1842
1843        assert_eq!(view[0], None);
1844        assert_eq!(view[0], None);
1845        assert_eq!(view[0], None);
1846        assert_eq!(view.len(), 3);
1847    }
1848
1849    #[test]
1850    fn peek_amount_zero() {
1851        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1852        let view = peeking_queue.peek_amount(0);
1853
1854        assert_eq!(view.len(), 0);
1855    }
1856
1857    #[test]
1858    fn peek_amount_match() {
1859        let mut peeking_queue = ["call", "f", "1"].iter().peekmore();
1860        let view = peeking_queue.peek_amount(4);
1861
1862        let value = match view {
1863            [Some(&"call"), Some(&"f"), Some(arg), None] => arg,
1864            _ => panic!("test case peek_n_match failed"),
1865        };
1866
1867        assert_eq!(**value, "1");
1868        assert_eq!(view.len(), 4);
1869    }
1870
1871    #[test]
1872    fn peek_amount_renewed_view() {
1873        let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
1874        let view = peeking_queue.peek_amount(2);
1875
1876        assert_eq!(view[0], Some(&0));
1877        assert_eq!(view[1], Some(&1));
1878
1879        let _removed = peeking_queue.next();
1880
1881        let view = peeking_queue.peek_amount(2);
1882
1883        assert_eq!(view[0], Some(&1));
1884        assert_eq!(view[1], Some(&2));
1885    }
1886
1887    #[test]
1888    fn next_if_works() {
1889        let iterable = [1, 2, 3, 4];
1890
1891        let mut iter = iterable.iter().peekmore();
1892
1893        assert_eq!(iter.next_if(|&x| *x == 1), Some(&1));
1894
1895        assert_eq!(iter.peek(), Some(&&2));
1896        assert_eq!(iter.next_if(|&x| *x < 4), Some(&2));
1897        assert_eq!(iter.peek(), Some(&&3));
1898
1899        assert_eq!(iter.peek(), Some(&&3));
1900        assert_eq!(iter.next_if(|&x| *x != 3), None);
1901        assert_eq!(iter.peek(), Some(&&3));
1902
1903        assert_eq!(iter.next(), Some(&3));
1904        assert_eq!(iter.next_if(|&_x| true), Some(&4));
1905    }
1906
1907    #[test]
1908    fn next_if_exhausted() {
1909        let iterable = [1, 2];
1910
1911        let mut iter = iterable.iter().peekmore();
1912
1913        assert_eq!(iter.next_if(|&x| *x == 1), Some(&1));
1914        assert_eq!(iter.next_if(|&x| *x == 2), Some(&2));
1915
1916        assert_eq!(iter.next_if(|&x| *x == 2), None);
1917    }
1918
1919    #[test]
1920    fn next_if_loop() {
1921        let iterable = 1..15;
1922
1923        let mut iter = iterable.peekmore();
1924
1925        while iter.next_if(|&x| x < 10).is_some() {}
1926        assert_eq!(iter.next(), Some(10));
1927    }
1928
1929    #[test]
1930    fn next_if_with_advanced_cursor() {
1931        let iterable = [1, 2, 3, 4];
1932
1933        let mut iter = iterable.iter().peekmore();
1934
1935        assert_eq!(iter.peek(), Some(&&1));
1936        let iter = iter.advance_cursor();
1937        let iter = iter.advance_cursor();
1938        assert_eq!(iter.peek(), Some(&&3));
1939        assert_eq!(iter.next_if(|&x| *x == 1), Some(&1));
1940        assert_eq!(iter.peek(), Some(&&3));
1941        assert_eq!(iter.next_if(|&x| *x == 2), Some(&2));
1942    }
1943
1944    #[test]
1945    fn next_if_eq_works() {
1946        let iterable = [1, 2, 3, 4];
1947
1948        let mut iter = iterable.iter().peekmore();
1949
1950        assert_eq!(iter.next_if_eq(&&1), Some(&1));
1951
1952        assert_eq!(iter.peek(), Some(&&2));
1953        assert_eq!(iter.next_if_eq(&&2), Some(&2));
1954        assert_eq!(iter.peek(), Some(&&3));
1955
1956        assert_eq!(iter.peek(), Some(&&3));
1957        assert_eq!(iter.next_if_eq(&&0), None);
1958        assert_eq!(iter.peek(), Some(&&3));
1959
1960        assert_eq!(iter.next_if_eq(&&3), Some(&3));
1961        assert_eq!(iter.next_if_eq(&&4), Some(&4));
1962
1963        assert_eq!(iter.next_if_eq(&&5), None);
1964    }
1965}