From a266a5b82dd7713c75787764c7aa7c18d1bc7375 Mon Sep 17 00:00:00 2001 From: Sean Olson Date: Fri, 9 Sep 2022 15:31:38 -0700 Subject: [PATCH] Implement `PeekingNext` for `PeekingTakeWhile`. 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`. --- src/peeking_take_while.rs | 12 ++++++++++++ tests/peeking_take_while.rs | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/peeking_take_while.rs b/src/peeking_take_while.rs index b3a9c5ccb..e808de988 100644 --- a/src/peeking_take_while.rs +++ b/src/peeking_take_while.rs @@ -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(&mut self, g: G) -> Option + 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 { diff --git a/tests/peeking_take_while.rs b/tests/peeking_take_while.rs index a1147027e..5be97271d 100644 --- a/tests/peeking_take_while.rs +++ b/tests/peeking_take_while.rs @@ -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)); +}