Skip to content

Commit

Permalink
Merge #644
Browse files Browse the repository at this point in the history
644: Implement `PeekingNext` for `PeekingTakeWhile`. r=jswrenn a=olson-sean-k

This PR implements `PeekingNext` for `PeekingTakeWhile` by composing its predicate with the predicate given to `PeekingNext::peeking_next`. This allows `Itertools::peeking_take_while` to be chained and for subsequent calls, including those across function boundaries, to function as expected while restoring items in the originating iterator.

See also #643, which implements `PeekingNext` for mutable references. In combination, these changes allow code to generically accept types implementing `PeekingNext` where `Itertools::peeking_take_while` can be used by the caller to prepare an iterator and subsequently by a function where restoring items in the originating iterator is important (i.e., the function cannot simply use `Iterator::peekable` etc., because `Iterator::next` would unconditionally be called on the originating iterator).

Co-authored-by: Sean Olson <olson.sean.k@gmail.com>
  • Loading branch information
bors[bot] and olson-sean-k committed Jun 15, 2023
2 parents 8bc377e + a266a5b commit 8184e4c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/peeking_take_while.rs
Expand Up @@ -115,6 +115,18 @@ impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>
}
}

impl<'a, I, F> PeekingNext for PeekingTakeWhile<'a, I, F>
where I: PeekingNext,
F: FnMut(&I::Item) -> bool,
{
fn peeking_next<G>(&mut self, g: G) -> Option<Self::Item>
where G: FnOnce(&Self::Item) -> bool,
{
let f = &mut self.f;
self.iter.peeking_next(|r| f(r) && g(r))
}
}

// Some iterators are so lightweight we can simply clone them to save their
// state and use that for peeking.
macro_rules! peeking_next_by_clone {
Expand Down
19 changes: 19 additions & 0 deletions tests/peeking_take_while.rs
Expand Up @@ -48,3 +48,22 @@ fn peeking_take_while_slice_iter_rev() {
r.peeking_take_while(|_| true).count();
assert_eq!(r.next(), None);
}

#[test]
fn peeking_take_while_nested() {
let mut xs = (0..10).peekable();
let ys: Vec<_> = xs
.peeking_take_while(|x| *x < 6)
.peeking_take_while(|x| *x != 3)
.collect();
assert_eq!(ys, vec![0, 1, 2]);
assert_eq!(xs.next(), Some(3));

let mut xs = (4..10).peekable();
let ys: Vec<_> = xs
.peeking_take_while(|x| *x != 3)
.peeking_take_while(|x| *x < 6)
.collect();
assert_eq!(ys, vec![4, 5]);
assert_eq!(xs.next(), Some(6));
}

0 comments on commit 8184e4c

Please sign in to comment.