Skip to content

Commit 8184e4c

Browse files
Merge #644
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 <[email protected]>
2 parents 8bc377e + a266a5b commit 8184e4c

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/peeking_take_while.rs

+12
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>
115115
}
116116
}
117117

118+
impl<'a, I, F> PeekingNext for PeekingTakeWhile<'a, I, F>
119+
where I: PeekingNext,
120+
F: FnMut(&I::Item) -> bool,
121+
{
122+
fn peeking_next<G>(&mut self, g: G) -> Option<Self::Item>
123+
where G: FnOnce(&Self::Item) -> bool,
124+
{
125+
let f = &mut self.f;
126+
self.iter.peeking_next(|r| f(r) && g(r))
127+
}
128+
}
129+
118130
// Some iterators are so lightweight we can simply clone them to save their
119131
// state and use that for peeking.
120132
macro_rules! peeking_next_by_clone {

tests/peeking_take_while.rs

+19
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,22 @@ fn peeking_take_while_slice_iter_rev() {
4848
r.peeking_take_while(|_| true).count();
4949
assert_eq!(r.next(), None);
5050
}
51+
52+
#[test]
53+
fn peeking_take_while_nested() {
54+
let mut xs = (0..10).peekable();
55+
let ys: Vec<_> = xs
56+
.peeking_take_while(|x| *x < 6)
57+
.peeking_take_while(|x| *x != 3)
58+
.collect();
59+
assert_eq!(ys, vec![0, 1, 2]);
60+
assert_eq!(xs.next(), Some(3));
61+
62+
let mut xs = (4..10).peekable();
63+
let ys: Vec<_> = xs
64+
.peeking_take_while(|x| *x != 3)
65+
.peeking_take_while(|x| *x < 6)
66+
.collect();
67+
assert_eq!(ys, vec![4, 5]);
68+
assert_eq!(xs.next(), Some(6));
69+
}

0 commit comments

Comments
 (0)