Skip to content

Commit

Permalink
Implement PeekingNext for PeekingTakeWhile.
Browse files Browse the repository at this point in the history
This change implements `PeekingNext` for `PeekingTakeWhile` by composing
its predicate with the predicate given to `PeekingNext::peeking_next`.
This allows subsequent (and chained) calls to functions that require
`PeekingNext` following `Itertools::peeking_take_while`.
  • Loading branch information
olson-sean-k committed Sep 12, 2022
1 parent 7883f59 commit a266a5b
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 a266a5b

Please sign in to comment.