diff --git a/README.md b/README.md index 67a85b4..928a4cd 100644 --- a/README.md +++ b/README.md @@ -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)); ``` diff --git a/src/lib.rs b/src/lib.rs index c8d0da1..b802fb3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,7 +68,18 @@ impl FullyPeekableIterator { 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> { + 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 { @@ -86,6 +97,12 @@ impl FullyPeekableIterator { 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> { + 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> { @@ -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] @@ -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(); @@ -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]