Skip to content

Commit

Permalink
chore: actually implement peak_many
Browse files Browse the repository at this point in the history
  • Loading branch information
clintval committed Oct 15, 2023
1 parent af6a9ee commit 088a76e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 9 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ Peek forward in an iterator as far as you'd like, memory allowing!
![El Chorro, Spain](.github/img/cover.jpg)

```rust
let iter = vec![1, 2].into_iter();
let iter = vec![1, 2, 3, 4].into_iter();
let mut peekable = iter.fully_peekable();
assert_eq!(peekable.peek(), Some(&1));
assert_eq!(peekable.next(), Some(1));
assert_eq!(peekable.peek(), Some(&2));
assert_eq!(peekable.next(), Some(2));
assert_eq!(peekable.peek(), None);

assert_eq!(peekable.lift_many(1, 3), vec!(Some(&2), Some(&3)));
assert_eq!(peekable.next(), Some(1));
assert_eq!(peekable.peek_many(3), vec!(Some(&2), Some(&3), Some(&4)));
assert_eq!(peekable.next(), Some(2));
assert_eq!(peekable.peek_many(3), vec!(Some(&3), Some(&4), None));
```
53 changes: 50 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,18 @@ impl<I: Iterator> FullyPeekableIterator<I> {
self.queue.get(index)
}

/// Peek forward to an arbitrary element without advancing the iterator.
/// Peek forward to a range of arbitrary elements without advancing the iterator.
#[inline]
pub fn lift_many(&mut self, start: usize, end: usize) -> Vec<Option<&I::Item>> {
self.lift(end.max(1) - 1); // Ensure we've filled the queue with as many items as necessary.
let mut result = Vec::with_capacity(end - start);
for index in start..end {
result.push(self.queue.get(index));
}
result
}

/// Peek forward to an arbitrary mutable element without advancing the iterator.
#[inline]
pub fn lift_mut(&mut self, index: usize) -> Option<&mut I::Item> {
while self.queue.len() <= index + 1 {
Expand All @@ -86,6 +97,12 @@ impl<I: Iterator> FullyPeekableIterator<I> {
self.lift(0)
}

/// Peek forward to a set number of arbitrary elements without advancing the iterator.
#[inline]
pub fn peek_many(&mut self, n: usize) -> Vec<Option<&I::Item>> {
self.lift_many(0, n)
}

/// Peek forward to the next element marking it as mutable without advancing the iterator.
#[inline]
pub fn peek_mut(&mut self) -> Option<&mut I::Item> {
Expand Down Expand Up @@ -184,7 +201,20 @@ mod tests {
assert_eq!(peekable.lift(2), None);
assert_eq!(peekable.next(), Some(1));
assert_eq!(peekable.next(), Some(2));
assert_eq!(peekable.peek(), None);
assert_eq!(peekable.next(), None);
}

#[test]
fn it_can_lift_many_elements_without_advancing() {
let iter = vec![1, 2].into_iter();
let mut peekable = FullyPeekableIterator::new(iter);
assert_eq!(peekable.lift_many(0, 1), vec!(Some(&1)));
assert_eq!(peekable.lift_many(0, 2), vec!(Some(&1), Some(&2)));
assert_eq!(peekable.lift_many(1, 3), vec!(Some(&2), None));
assert_eq!(peekable.lift_many(5, 7), vec!(None, None));
assert_eq!(peekable.next(), Some(1));
assert_eq!(peekable.next(), Some(2));
assert_eq!(peekable.next(), None);
}

#[test]
Expand All @@ -199,6 +229,23 @@ mod tests {
assert_eq!(peekable.next(), None);
}

#[test]
fn it_can_peek_many_elements_without_advancing() {
let iter = vec![1, 2].into_iter();
let mut peekable = iter.fully_peekable();
assert_eq!(peekable.peek_many(0), vec!());
assert_eq!(peekable.peek_many(1), vec!(Some(&1)));
assert_eq!(peekable.peek_many(2), vec!(Some(&1), Some(&2)));
assert_eq!(peekable.peek_many(3), vec!(Some(&1), Some(&2), None));
assert_eq!(peekable.next(), Some(1));
assert_eq!(peekable.peek_many(1), vec!(Some(&2)));
assert_eq!(peekable.peek_many(2), vec!(Some(&2), None));
assert_eq!(peekable.next(), Some(2));
assert_eq!(peekable.peek_many(1), vec!(None));
assert_eq!(peekable.peek_many(2), vec!(None, None));
assert_eq!(peekable.peek_many(0), vec!());
}

#[test]
fn it_can_lift_elements_without_advancing_mut() {
let iter = vec![1, 2].into_iter();
Expand All @@ -208,7 +255,7 @@ mod tests {
assert_eq!(peekable.lift_mut(2), None);
assert_eq!(peekable.next(), Some(1));
assert_eq!(peekable.next(), Some(2));
assert_eq!(peekable.peek(), None);
assert_eq!(peekable.next(), None);
}

#[test]
Expand Down

0 comments on commit 088a76e

Please sign in to comment.