1pub struct StopOnce<I, P> {
4 iter: Option<I>,
5 is_last: P,
6}
7
8impl<I: Iterator, P: FnMut(&I::Item) -> bool> Iterator for StopOnce<I, P> {
9 type Item = I::Item;
10
11 fn next(&mut self) -> Option<Self::Item> {
12 let item = self.iter.as_mut()?.next()?;
13 if (self.is_last)(&item) {
14 self.iter = None;
15 }
16 Some(item)
17 }
18}
19
20pub trait Stopper: Iterator
21where
22 Self: Sized,
23{
24 fn stop_once<P: FnMut(&Self::Item) -> bool>(self, predicate: P) -> StopOnce<Self, P>;
26}
27
28impl<I: Iterator> Stopper for I {
29 fn stop_once<P: FnMut(&Self::Item) -> bool>(self, predicate: P) -> StopOnce<Self, P> {
30 StopOnce {
31 iter: Some(self),
32 is_last: predicate,
33 }
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn stop_once_includes_terminal() {
43 let items: Vec<_> = (1..10).stop_once(|&x| x == 5).collect();
44 assert_eq!(items, vec![1, 2, 3, 4, 5]);
45 }
46
47 #[test]
48 fn stop_once_empty_if_first_matches() {
49 let items: Vec<_> = (1..10).stop_once(|&x| x == 1).collect();
50 assert_eq!(items, vec![1]);
51 }
52
53 #[test]
54 fn stop_once_all_if_none_match() {
55 let items: Vec<_> = (1..5).stop_once(|&x| x == 10).collect();
56 assert_eq!(items, vec![1, 2, 3, 4]);
57 }
58}