#![no_std]
#![deny(missing_docs)]
#![deny(clippy::all)]
extern crate alloc;
#[cfg(doctest)]
extern crate std;
#[cfg(doctest)]
#[global_allocator]
static A: std::alloc::System = std::alloc::System;
use core::iter::FusedIterator;
#[cfg(not(feature = "smallvec"))]
use alloc::vec::Vec;
#[cfg(feature = "smallvec")]
use smallvec::SmallVec;
pub trait PeekMore: Iterator + Sized {
fn peekmore(self) -> PeekMoreIterator<Self>;
}
impl<I: Iterator> PeekMore for I {
fn peekmore(self) -> PeekMoreIterator<I> {
PeekMoreIterator {
iterator: self,
#[cfg(not(feature = "smallvec"))]
queue: Vec::new(),
#[cfg(feature = "smallvec")]
queue: SmallVec::new(),
cursor: 0usize,
}
}
}
#[cfg(feature = "smallvec")]
const DEFAULT_STACK_SIZE: usize = 8;
#[derive(Clone, Debug)]
pub struct PeekMoreIterator<I: Iterator> {
iterator: I,
#[cfg(not(feature = "smallvec"))]
queue: Vec<Option<I::Item>>,
#[cfg(feature = "smallvec")]
queue: SmallVec<[Option<I::Item>; DEFAULT_STACK_SIZE]>,
cursor: usize,
}
impl<I: Iterator> PeekMoreIterator<I> {
#[inline]
pub fn peek(&mut self) -> Option<&I::Item> {
self.fill_queue(self.cursor);
self.queue.get(self.cursor).and_then(|v| v.as_ref())
}
#[inline]
pub fn peek_first(&mut self) -> Option<&I::Item> {
self.peek_nth(0)
}
#[inline]
pub fn peek_next(&mut self) -> Option<&I::Item> {
let this = self.advance_cursor();
this.peek()
}
#[inline]
pub fn peek_previous(&mut self) -> Result<Option<&I::Item>, PeekMoreError> {
if self.cursor >= 1 {
self.move_cursor_back().map(|iter| iter.peek())
} else {
Err(PeekMoreError::ElementHasBeenConsumed)
}
}
#[inline]
pub fn peek_forward(&mut self, n: usize) -> Option<&I::Item> {
let this = self.advance_cursor_by(n);
this.peek()
}
#[inline]
pub fn peek_backward(&mut self, n: usize) -> Result<Option<&I::Item>, PeekMoreError> {
let _ = self.move_cursor_back_by(n)?;
Ok(self.peek())
}
#[inline]
pub fn peek_backward_or_first(&mut self, n: usize) -> Option<&I::Item> {
if self.move_cursor_back_by(n).is_err() {
self.reset_cursor();
}
self.peek()
}
#[inline]
pub fn peek_nth(&mut self, n: usize) -> Option<&I::Item> {
self.fill_queue(n);
self.queue.get(n).and_then(|v| v.as_ref())
}
#[inline]
pub fn advance_cursor(&mut self) -> &mut PeekMoreIterator<I> {
self.increment_cursor();
self
}
#[inline]
pub fn advance_cursor_by(&mut self, n: usize) -> &mut PeekMoreIterator<I> {
self.cursor += n;
self
}
#[inline]
pub fn advance_cursor_while<P: Fn(Option<&I::Item>) -> bool>(
&mut self,
predicate: P,
) -> &mut PeekMoreIterator<I> {
let view = self.peek();
if predicate(view) {
self.increment_cursor();
self.advance_cursor_while(predicate)
} else {
self
}
}
#[inline]
pub fn move_cursor_back(&mut self) -> Result<&mut PeekMoreIterator<I>, PeekMoreError> {
if self.cursor >= 1 {
self.decrement_cursor();
Ok(self)
} else {
Err(PeekMoreError::ElementHasBeenConsumed)
}
}
#[inline]
pub fn move_cursor_back_by(
&mut self,
n: usize,
) -> Result<&mut PeekMoreIterator<I>, PeekMoreError> {
if self.cursor < n {
Err(PeekMoreError::ElementHasBeenConsumed)
} else {
self.cursor -= n;
Ok(self)
}
}
#[inline]
pub fn move_cursor_back_or_reset(&mut self, n: usize) -> &mut PeekMoreIterator<I> {
if self.cursor < n {
self.reset_cursor();
} else {
self.cursor -= n;
}
self
}
#[inline]
pub fn move_nth(&mut self, n: usize) -> &mut PeekMoreIterator<I> {
self.cursor = n;
self
}
#[deprecated]
#[inline]
pub fn reset_view(&mut self) {
self.reset_cursor()
}
#[inline]
pub fn reset_cursor(&mut self) {
self.cursor = 0;
}
#[inline]
pub fn cursor(&self) -> usize {
self.cursor
}
#[inline]
fn fill_queue(&mut self, required_elements: usize) {
let stored_elements = self.queue.len();
if stored_elements <= required_elements {
for _ in stored_elements..=required_elements {
self.push_next_to_queue()
}
}
}
#[inline]
fn push_next_to_queue(&mut self) {
let item = self.iterator.next();
self.queue.push(item);
}
#[inline]
fn increment_cursor(&mut self) {
self.cursor = self.cursor.saturating_add(1);
}
#[inline]
fn decrement_cursor(&mut self) {
if self.cursor > core::usize::MIN {
self.cursor -= 1;
}
}
pub fn truncate_iterator_to_cursor(&mut self) {
if self.cursor < self.queue.len() {
self.queue.drain(0..self.cursor);
} else {
for _ in 0..self.cursor.saturating_sub(self.queue.len()) {
let _ = self.iterator.next();
}
self.queue.clear();
}
self.cursor = 0;
}
pub fn peek_range(&mut self, start: usize, end: usize) -> &[Option<I::Item>] {
assert!(
start <= end,
"range of the peeked view [start, end] should be positive (i.e. start <= end)"
);
if end > self.queue.len() {
self.fill_queue(end);
}
&self.queue.as_slice()[start..end]
}
#[inline]
pub fn peek_amount(&mut self, n: usize) -> &[Option<I::Item>] {
self.peek_range(0, n)
}
#[inline]
pub fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item> {
match self.peek_first() {
Some(matched) if func(matched) => self.next(),
_ => None,
}
}
#[inline]
pub fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
where
T: ?Sized,
I::Item: PartialEq<T>,
{
self.next_if(|next| next == expected)
}
}
impl<I: Iterator> Iterator for PeekMoreIterator<I> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
let res = if self.queue.is_empty() {
self.iterator.next()
} else {
self.queue.remove(0)
};
self.decrement_cursor();
res
}
}
impl<I: ExactSizeIterator> ExactSizeIterator for PeekMoreIterator<I> {}
impl<I: FusedIterator> FusedIterator for PeekMoreIterator<I> {}
#[derive(Debug, Eq, PartialEq)]
pub enum PeekMoreError {
ElementHasBeenConsumed,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn readme_example() {
let range10 = 0..11;
let mut peekable = range10.peekmore();
let peek_first = peekable.peek();
assert_eq!(*peek_first.unwrap(), 0);
let peek_first_redux = peekable.peek_nth(0);
assert_eq!(*peek_first_redux.unwrap(), 0);
let peek_tenth = peekable.peek_nth(10);
assert_eq!(*peek_tenth.unwrap(), 10);
let tenth = peekable.nth(10);
assert_eq!(tenth.unwrap(), 10);
assert_eq!(peekable.peek(), None);
assert_eq!(peekable.next(), None);
}
#[test]
fn peek_forward_with_reassignment() {
let iterable = [1, 2, 3, 4];
let mut peek = iterable.iter().peekmore();
assert_eq!(peek.peek(), Some(&&1));
let peek = peek.advance_cursor();
assert_eq!(peek.peek(), Some(&&2));
let peek = peek.advance_cursor();
assert_eq!(peek.peek(), Some(&&3));
let peek = peek.advance_cursor();
assert_eq!(peek.peek(), Some(&&4));
let peek = peek.advance_cursor();
assert_eq!(peek.peek(), None);
}
#[test]
fn peek_forward_without_reassignment_separately_advance_and_peek() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.peek(), Some(&&1));
let v2 = iter.advance_cursor().peek();
assert_eq!(v2, Some(&&2));
let v3 = iter.advance_cursor().peek();
assert_eq!(v3, Some(&&3));
let v4 = iter.advance_cursor().peek();
assert_eq!(v4, Some(&&4));
let v5 = iter.advance_cursor().peek();
assert_eq!(v5, None);
}
#[test]
fn peek_forward_without_reassignment_advance_and_peek_combined() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let v1 = iter.peek();
assert_eq!(v1, Some(&&1));
let v2 = iter.peek_next();
assert_eq!(v2, Some(&&2));
let v3 = iter.peek_next();
assert_eq!(v3, Some(&&3));
let v4 = iter.peek_next();
assert_eq!(v4, Some(&&4));
let v5 = iter.peek_next();
assert_eq!(v5, None);
}
#[test]
fn peek_forward_without_reassignment_advance_and_peek_combined_and_reset_view() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let v1 = iter.peek();
assert_eq!(v1, Some(&&1));
let v2 = iter.peek_next();
assert_eq!(v2, Some(&&2));
iter.reset_cursor();
let v1again = iter.peek();
assert_eq!(v1again, Some(&&1));
let v2again = iter.peek_next();
assert_eq!(v2again, Some(&&2));
let v3 = iter.peek_next();
assert_eq!(v3, Some(&&3));
let v4 = iter.peek_next();
assert_eq!(v4, Some(&&4));
let v5 = iter.peek_next();
assert_eq!(v5, None);
}
#[test]
fn empty() {
let iterable: [i32; 0] = [];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.peek(), None);
let none = iter.peek_next();
assert_eq!(none, None);
let iter = iter.advance_cursor();
assert_eq!(iter.peek(), None);
assert_eq!(iter.peek_next(), None);
}
#[test]
fn test_with_consume() {
let iterable = "123".chars();
let mut iter = iterable.peekmore();
assert_eq!(iter.peek(), Some(&core::char::from_digit(1, 10).unwrap()));
assert_eq!(
iter.peek_next(),
Some(&core::char::from_digit(2, 10).unwrap())
);
assert_eq!(
iter.peek_next(),
Some(&core::char::from_digit(3, 10).unwrap())
);
assert_eq!(iter.peek_next(), None);
assert_eq!(iter.next(), Some(core::char::from_digit(1, 10).unwrap()));
assert_eq!(iter.peek(), None);
assert_eq!(iter.peek_next(), None);
assert_eq!(iter.next(), Some(core::char::from_digit(2, 10).unwrap()));
assert_eq!(iter.peek(), None);
assert_eq!(iter.peek_next(), None);
assert_eq!(iter.next(), Some(core::char::from_digit(3, 10).unwrap()));
assert_eq!(iter.next(), None);
assert_eq!(iter.peek_next(), None);
}
#[test]
fn test_with_consume_and_reset() {
let iterable = "456".chars();
let mut iter = iterable.peekmore();
assert_eq!(iter.peek(), Some(&core::char::from_digit(4, 10).unwrap()));
assert_eq!(
iter.peek_next(),
Some(&core::char::from_digit(5, 10).unwrap())
);
assert_eq!(
iter.peek_next(),
Some(&core::char::from_digit(6, 10).unwrap())
);
assert_eq!(iter.peek_next(), None);
assert_eq!(iter.next(), Some(core::char::from_digit(4, 10).unwrap()));
iter.reset_cursor();
assert_eq!(iter.peek(), Some(&core::char::from_digit(5, 10).unwrap()));
assert_eq!(
iter.peek_next(),
Some(&core::char::from_digit(6, 10).unwrap())
);
assert_eq!(iter.next(), Some(core::char::from_digit(5, 10).unwrap()));
assert_eq!(iter.next(), Some(core::char::from_digit(6, 10).unwrap()));
assert_eq!(iter.next(), None);
assert_eq!(iter.peek_next(), None);
}
#[test]
fn check_peek_window_moves_with_consume() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let v1 = iter.peek();
assert_eq!(v1, Some(&&1));
let v1c = iter.next();
assert_eq!(v1c, Some(&1));
let v2 = iter.peek();
assert_eq!(v2, Some(&&2));
let v2c = iter.next();
assert_eq!(v2c, Some(&2));
let v3 = iter.peek();
assert_eq!(v3, Some(&&3));
iter.reset_cursor();
let v3 = iter.peek();
assert_eq!(v3, Some(&&3));
let v3c = iter.next();
assert_eq!(v3c, Some(&3));
let v4c = iter.next();
assert_eq!(v4c, Some(&4));
let v5 = iter.peek();
assert_eq!(v5, None);
let v5c = iter.next();
assert_eq!(v5c, None);
}
#[test]
fn check_advance_separately() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.cursor(), 0);
assert_eq!(iter.peek(), Some(&&1));
iter.advance_cursor(); assert_eq!(iter.cursor(), 1);
iter.advance_cursor(); assert_eq!(iter.cursor(), 2);
iter.advance_cursor(); assert_eq!(iter.cursor(), 3);
let v4 = iter.peek();
assert_eq!(v4, Some(&&4));
}
#[test]
fn check_advance_chain() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.cursor(), 0);
iter.advance_cursor() .advance_cursor() .advance_cursor();
let v4 = iter.peek();
assert_eq!(v4, Some(&&4));
}
#[test]
fn check_move_previous() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.cursor(), 0);
assert_eq!(iter.peek(), Some(&&1));
iter.advance_cursor(); assert_eq!(iter.cursor(), 1);
let _ = iter.move_cursor_back(); assert_eq!(iter.cursor(), 0);
iter.advance_cursor(); assert_eq!(iter.cursor(), 1);
let _ = iter.move_cursor_back(); assert_eq!(iter.cursor(), 0);
iter.advance_cursor(); assert_eq!(iter.cursor(), 1);
iter.advance_cursor() .advance_cursor();
assert_eq!(iter.cursor(), 3);
let v4 = iter.peek();
assert_eq!(v4, Some(&&4));
let _ = iter.move_cursor_back().and_then(|it| {
it.move_cursor_back() .and_then(|it| {
it.move_cursor_back() .and_then(|it| it.move_cursor_back())
})
});
let v1 = iter.peek();
assert_eq!(v1, Some(&&1));
let prev = iter.move_cursor_back();
assert!(prev.is_err());
let v1 = iter.peek();
assert_eq!(v1, Some(&&1));
}
#[test]
fn test_with_inherited_feature_count() {
let iterable = [1, 2, 3];
let mut iter = iterable.iter().peekmore();
iter.advance_cursor();
let second = iter.peek().unwrap();
assert_eq!(second, &&2);
let consume_first = iter.next().unwrap();
assert_eq!(consume_first, &1);
let count = iter.count();
assert_eq!(count, 2);
}
#[test]
fn peek_previous() {
let iterable = [1, 2, 3];
let mut iter = iterable.iter().peekmore();
iter.advance_cursor(); iter.advance_cursor(); let value = iter.peek().unwrap(); assert_eq!(value, &&3);
let peek = iter.peek_previous(); assert_eq!(peek.unwrap(), Some(&&2));
assert_eq!(iter.cursor(), 1);
let peek = iter.peek_previous(); assert_eq!(peek.unwrap(), Some(&&1));
assert_eq!(iter.cursor(), 0);
let peek = iter.peek_previous();
assert_eq!(peek, Err(PeekMoreError::ElementHasBeenConsumed));
assert_eq!(iter.cursor(), 0);
}
#[test]
fn peek_previous_beyond_none() {
let iterable = [1];
let mut iter = iterable.iter().peekmore(); assert_eq!(iter.cursor(), 0);
iter.advance_cursor(); let peek = iter.peek();
assert_eq!(peek, None);
assert_eq!(iter.cursor(), 1);
iter.advance_cursor(); let peek = iter.peek();
assert_eq!(peek, None);
assert_eq!(iter.cursor(), 2);
iter.advance_cursor(); let peek = iter.peek(); assert_eq!(peek, None);
assert_eq!(iter.cursor(), 3);
let peek = iter.peek_previous(); assert_eq!(peek.unwrap(), None);
assert_eq!(iter.cursor(), 2);
let peek = iter.peek_previous(); assert_eq!(peek.unwrap(), None);
assert_eq!(iter.cursor(), 1);
let peek = iter.peek_previous(); assert_eq!(peek.unwrap(), Some(&&1));
assert_eq!(iter.cursor(), 0);
let peek = iter.peek_previous();
assert_eq!(peek, Err(PeekMoreError::ElementHasBeenConsumed));
assert_eq!(iter.cursor(), 0);
let peek = iter.peek_previous();
assert_eq!(peek, Err(PeekMoreError::ElementHasBeenConsumed));
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_move_forward() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, None);
assert_eq!(iter.cursor(), 6);
}
#[test]
fn check_move_backward() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let result = iter.move_cursor_back_by(2);
assert!(result.is_ok());
let peek = iter.peek();
assert_eq!(peek, Some(&&2));
assert_eq!(iter.cursor(), 1);
let result = iter.move_cursor_back_by(1);
assert!(result.is_ok());
let peek = iter.peek();
assert_eq!(peek, Some(&&1));
assert_eq!(iter.cursor(), 0);
let result = iter.move_cursor_back_by(1);
assert!(result.is_err());
let peek = iter.peek();
assert_eq!(peek, Some(&&1));
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_move_backward_beyond_consumed_verify_cursor_position() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let result = iter.move_cursor_back_by(5);
assert!(result.is_err());
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
}
#[test]
fn check_move_backward_or_reset() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let _ = iter.move_cursor_back_or_reset(2);
let peek = iter.peek();
assert_eq!(peek, Some(&&2));
assert_eq!(iter.cursor(), 1);
let _ = iter.move_cursor_back_or_reset(1);
let peek = iter.peek();
assert_eq!(peek, Some(&&1));
assert_eq!(iter.cursor(), 0);
let _ = iter.move_cursor_back_or_reset(1);
let peek = iter.peek();
assert_eq!(peek, Some(&&1));
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_move_backward_or_reset_beyond_consumed_verify_cursor_position() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let _ = iter.move_cursor_back_or_reset(5);
let peek = iter.peek();
assert_eq!(peek, Some(&&1));
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_move_backward_or_reset_empty() {
let iterable = "".chars();
let mut iter = iterable.peekmore();
assert_eq!(iter.peek(), None);
assert_eq!(iter.cursor(), 0);
let _ = iter.move_cursor_back_or_reset(5);
assert_eq!(iter.peek(), None);
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_peek_forward() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let peek = iter.peek_forward(3);
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let peek = iter.peek_forward(3);
assert_eq!(peek, None);
assert_eq!(iter.cursor(), 6);
}
#[test]
fn check_peek_backward() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let result = iter.peek_backward(2);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Some(&&2));
assert_eq!(iter.cursor(), 1);
let result = iter.peek_backward(1);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Some(&&1));
assert_eq!(iter.cursor(), 0);
let result = iter.peek_backward(1);
assert!(result.is_err());
let peek = iter.peek();
assert_eq!(peek, Some(&&1));
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_peek_backward_beyond_consumed_verify_cursor_position() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let result = iter.peek_backward(5);
assert!(result.is_err());
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
}
#[test]
fn check_peek_backward_or_first_beyond_consumed_verify_cursor_position() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_by(3);
let peek = iter.peek();
assert_eq!(peek, Some(&&4));
assert_eq!(iter.cursor(), 3);
let peek = iter.peek_backward_or_first(5);
assert_eq!(peek, Some(&&1));
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_peek_backward_or_first_empty() {
let iterable = "".chars();
let mut iter = iterable.peekmore();
assert_eq!(iter.peek(), None);
assert_eq!(iter.cursor(), 0);
let peek = iter.peek_backward_or_first(5);
assert_eq!(peek, None);
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_move_forward_while() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_while(|i| **i.unwrap() != 3);
let peek = iter.peek();
assert_eq!(peek, Some(&&3));
assert_eq!(iter.cursor(), 2);
}
#[test]
fn check_move_forward_while_empty() {
let iterable: [i32; 0] = [];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_while(|i| if let Some(i) = i { **i != 3 } else { false });
let peek = iter.peek();
assert_eq!(peek, None);
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_move_forward_while_some() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
let _ = iter.advance_cursor_while(|i| i.is_some());
let peek = iter.peek();
assert_eq!(peek, None);
assert_eq!(iter.cursor(), 4);
}
#[test]
fn check_move_forward_while_fast_fail() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
iter.advance_cursor_by(2);
let _ = iter.advance_cursor_while(|i| **i.unwrap() > 3);
let peek = iter.peek();
assert_eq!(peek, Some(&&3));
assert_eq!(iter.cursor(), 2);
}
#[test]
fn check_peek_nth() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.peek_nth(0), Some(&&1));
assert_eq!(iter.cursor(), 0);
assert_eq!(iter.peek_nth(1), Some(&&2));
assert_eq!(iter.cursor(), 0);
assert_eq!(iter.peek_nth(2), Some(&&3));
assert_eq!(iter.cursor(), 0);
assert_eq!(iter.peek_nth(3), Some(&&4));
assert_eq!(iter.cursor(), 0);
assert_eq!(iter.peek_nth(4), None);
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_peek_first() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.peek_first(), Some(&&1));
assert_eq!(iter.cursor(), 0);
iter.increment_cursor();
assert_eq!(iter.peek_first(), Some(&&1));
assert_eq!(iter.cursor(), 1);
iter.increment_cursor();
assert_eq!(iter.peek_first(), Some(&&1));
assert_eq!(iter.cursor(), 2);
iter.increment_cursor();
assert_eq!(iter.peek_first(), Some(&&1));
assert_eq!(iter.cursor(), 3);
iter.increment_cursor(); assert_eq!(iter.peek_first(), Some(&&1));
iter.next();
assert_eq!(iter.peek_first(), Some(&&2));
iter.increment_cursor();
assert_eq!(iter.peek_first(), Some(&&2));
iter.next(); iter.next(); assert_eq!(iter.peek_first(), Some(&&4));
iter.next();
assert_eq!(iter.peek_first(), None);
}
#[test]
fn check_peek_nth_empty() {
let iterable: [i32; 0] = [];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.peek_nth(0), None);
assert_eq!(iter.cursor(), 0);
assert_eq!(iter.peek_nth(1), None);
assert_eq!(iter.cursor(), 0);
}
#[test]
fn check_move_nth() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
iter.move_nth(20);
assert_eq!(iter.peek_nth(0), Some(&&1));
assert_eq!(iter.cursor(), 20);
assert_eq!(iter.peek(), None);
iter.move_nth(0);
assert_eq!(iter.peek(), Some(&&1));
iter.move_nth(3);
assert_eq!(iter.peek(), Some(&&4));
}
#[test]
fn check_move_nth_empty() {
let iterable: [i32; 0] = [];
let mut iter = iterable.iter().peekmore();
iter.move_nth(0);
assert_eq!(iter.cursor(), 0);
iter.move_nth(10);
assert_eq!(iter.cursor(), 10);
}
#[test]
fn truncate_iterator_to_cursor_is_noop_when_queue_is_empty_from_no_peeking() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert!(iter.queue.is_empty());
iter.truncate_iterator_to_cursor();
assert!(iter.queue.is_empty());
assert_eq!(iter.peek(), Some(&&1));
assert!(!iter.queue.is_empty());
}
#[test]
fn truncate_iterator_to_cursor_is_noop_when_queue_is_empty_from_iteration() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert!(iter.queue.is_empty());
iter.peek_forward(2);
iter.next();
iter.next();
iter.next();
assert!(iter.queue.is_empty());
iter.truncate_iterator_to_cursor();
assert!(iter.queue.is_empty());
assert_eq!(iter.peek(), Some(&&4));
assert!(!iter.queue.is_empty());
}
#[test]
fn truncate_to_iterator_fill_queue() {
let mut iter = [0, 1, 2, 3].iter().peekmore();
iter.advance_cursor();
iter.truncate_iterator_to_cursor();
let value = **iter.peek().unwrap();
assert_eq!(value, 1);
}
#[test]
fn truncate_to_iterator_on_empty_collection() {
let mut iter = core::iter::empty::<i32>().peekmore();
iter.advance_cursor();
assert_eq!(iter.cursor, 1);
iter.truncate_iterator_to_cursor();
assert_eq!(iter.cursor, 0);
assert!(iter.peek().is_none());
}
#[test]
fn truncate_to_iterator_on_single_element_collection() {
let mut iter = core::iter::once(0).peekmore();
assert_eq!(*iter.peek().unwrap(), 0);
assert_eq!(iter.cursor, 0);
iter.advance_cursor(); assert_eq!(iter.cursor, 1);
assert!(iter.peek().is_none());
iter.truncate_iterator_to_cursor();
assert_eq!(iter.cursor, 0);
assert!(iter.peek().is_none());
}
#[test]
fn truncate_to_iterator_cursor_and_queue_equal_length() {
let mut iter = [0, 1, 2, 3].iter().peekmore();
iter.peek();
iter.advance_cursor();
iter.truncate_iterator_to_cursor();
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
}
#[test]
fn truncate_to_iterator_cursor_less_than_queue_length() {
let mut iter = [0, 1, 2, 3].iter().peekmore();
iter.peek_nth(2);
iter.truncate_iterator_to_cursor();
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
let mut iter = [0, 1, 2, 3].iter().peekmore();
iter.peek_nth(3);
iter.advance_cursor();
iter.truncate_iterator_to_cursor();
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
}
#[test]
fn peek_range_from_start_smaller_than_input_len() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_range(0, 2);
assert_eq!(view[0], Some(&0));
assert_eq!(view[1], Some(&1));
assert_eq!(view.len(), 2);
}
#[test]
fn peek_range_from_start_eq_to_input_len() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_range(0, 4);
assert_eq!(view[0], Some(&0));
assert_eq!(view[1], Some(&1));
assert_eq!(view[2], Some(&2));
assert_eq!(view[3], Some(&3));
assert_eq!(view.len(), 4);
}
#[test]
fn peek_range_from_start_bigger_than_input_len() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_range(0, 6);
assert_eq!(view[0], Some(&0));
assert_eq!(view[1], Some(&1));
assert_eq!(view[2], Some(&2));
assert_eq!(view[3], Some(&3));
assert_eq!(view[4], None);
assert_eq!(view[5], None);
assert_eq!(view.len(), 6);
}
#[test]
fn peek_range_from_middle() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_range(2, 5);
assert_eq!(view[0], Some(&2));
assert_eq!(view[1], Some(&3));
assert_eq!(view[2], None);
assert_eq!(view.len(), 3);
}
#[test]
fn peek_range_out_of_bounds() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_range(5, 6);
assert_eq!(view[0], None);
assert_eq!(view.len(), 1);
}
#[test]
fn peek_range_empty() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_range(0, 0);
assert_eq!(view.len(), 0);
}
#[test]
fn peek_range_match() {
let mut peeking_queue = ["call", "f", "1"].iter().peekmore();
let view = peeking_queue.peek_range(1, 3);
let value = match view {
[Some(&"f"), Some(arg)] => arg,
_ => panic!("test case peek_range_match failed"),
};
assert_eq!(**value, "1");
assert_eq!(view.len(), 2);
}
#[test]
#[should_panic]
fn peek_range_panic_on_invalid_range() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let _ = peeking_queue.peek_range(2, 1);
}
#[test]
fn peek_amount_from_start_smaller_than_input_len() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_amount(2);
assert_eq!(view[0], Some(&0));
assert_eq!(view[1], Some(&1));
assert_eq!(view.len(), 2);
}
#[test]
fn peek_amount_from_start_eq_to_input_len() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_amount(4);
assert_eq!(view[0], Some(&0));
assert_eq!(view[1], Some(&1));
assert_eq!(view[2], Some(&2));
assert_eq!(view[3], Some(&3));
assert_eq!(view.len(), 4);
}
#[test]
fn peek_amount_from_start_bigger_than_input_len() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_amount(6);
assert_eq!(view[0], Some(&0));
assert_eq!(view[1], Some(&1));
assert_eq!(view[2], Some(&2));
assert_eq!(view[3], Some(&3));
assert_eq!(view[4], None);
assert_eq!(view[5], None);
assert_eq!(view.len(), 6);
}
#[test]
fn peek_amount_empty() {
let empty: [u32; 0] = [];
let mut peeking_queue = empty.iter().peekmore();
let view = peeking_queue.peek_amount(3);
assert_eq!(view[0], None);
assert_eq!(view[0], None);
assert_eq!(view[0], None);
assert_eq!(view.len(), 3);
}
#[test]
fn peek_amount_zero() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_amount(0);
assert_eq!(view.len(), 0);
}
#[test]
fn peek_amount_match() {
let mut peeking_queue = ["call", "f", "1"].iter().peekmore();
let view = peeking_queue.peek_amount(4);
let value = match view {
[Some(&"call"), Some(&"f"), Some(arg), None] => arg,
_ => panic!("test case peek_n_match failed"),
};
assert_eq!(**value, "1");
assert_eq!(view.len(), 4);
}
#[test]
fn peek_amount_renewed_view() {
let mut peeking_queue = [0, 1, 2, 3].iter().peekmore();
let view = peeking_queue.peek_amount(2);
assert_eq!(view[0], Some(&0));
assert_eq!(view[1], Some(&1));
let _removed = peeking_queue.next();
let view = peeking_queue.peek_amount(2);
assert_eq!(view[0], Some(&1));
assert_eq!(view[1], Some(&2));
}
#[test]
fn next_if_works() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.next_if(|&x| *x == 1), Some(&1));
assert_eq!(iter.peek(), Some(&&2));
assert_eq!(iter.next_if(|&x| *x < 4), Some(&2));
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.next_if(|&x| *x != 3), None);
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next_if(|&_x| true), Some(&4));
}
#[test]
fn next_if_exhausted() {
let iterable = [1, 2];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.next_if(|&x| *x == 1), Some(&1));
assert_eq!(iter.next_if(|&x| *x == 2), Some(&2));
assert_eq!(iter.next_if(|&x| *x == 2), None);
}
#[test]
fn next_if_loop() {
let iterable = 1..15;
let mut iter = iterable.peekmore();
while iter.next_if(|&x| x < 10).is_some() {}
assert_eq!(iter.next(), Some(10));
}
#[test]
fn next_if_with_advanced_cursor() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.peek(), Some(&&1));
let iter = iter.advance_cursor();
let iter = iter.advance_cursor();
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.next_if(|&x| *x == 1), Some(&1));
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.next_if(|&x| *x == 2), Some(&2));
}
#[test]
fn next_if_eq_works() {
let iterable = [1, 2, 3, 4];
let mut iter = iterable.iter().peekmore();
assert_eq!(iter.next_if_eq(&&1), Some(&1));
assert_eq!(iter.peek(), Some(&&2));
assert_eq!(iter.next_if_eq(&&2), Some(&2));
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.next_if_eq(&&0), None);
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.next_if_eq(&&3), Some(&3));
assert_eq!(iter.next_if_eq(&&4), Some(&4));
assert_eq!(iter.next_if_eq(&&5), None);
}
}