1 | use core::iter::FusedIterator; |
2 | use std::fmt; |
3 | |
4 | /// An iterator adaptor that consumes elements while the given predicate is |
5 | /// `true`, including the element for which the predicate first returned |
6 | /// `false`. |
7 | /// |
8 | /// See [`.take_while_inclusive()`](crate::Itertools::take_while_inclusive) |
9 | /// for more information. |
10 | #[must_use = "iterator adaptors are lazy and do nothing unless consumed" ] |
11 | pub struct TakeWhileInclusive<'a, I: 'a, F> { |
12 | iter: &'a mut I, |
13 | predicate: F, |
14 | done: bool, |
15 | } |
16 | |
17 | impl<'a, I, F> TakeWhileInclusive<'a, I, F> |
18 | where |
19 | I: Iterator, |
20 | F: FnMut(&I::Item) -> bool, |
21 | { |
22 | /// Create a new [`TakeWhileInclusive`] from an iterator and a predicate. |
23 | pub fn new(iter: &'a mut I, predicate: F) -> Self { |
24 | Self { iter, predicate, done: false} |
25 | } |
26 | } |
27 | |
28 | impl<'a, I, F> fmt::Debug for TakeWhileInclusive<'a, I, F> |
29 | where I: Iterator + fmt::Debug, |
30 | { |
31 | debug_fmt_fields!(TakeWhileInclusive, iter); |
32 | } |
33 | |
34 | impl<'a, I, F> Iterator for TakeWhileInclusive<'a, I, F> |
35 | where |
36 | I: Iterator, |
37 | F: FnMut(&I::Item) -> bool |
38 | { |
39 | type Item = I::Item; |
40 | |
41 | fn next(&mut self) -> Option<Self::Item> { |
42 | if self.done { |
43 | None |
44 | } else { |
45 | self.iter.next().map(|item: ::Item| { |
46 | if !(self.predicate)(&item) { |
47 | self.done = true; |
48 | } |
49 | item |
50 | }) |
51 | } |
52 | } |
53 | |
54 | fn size_hint(&self) -> (usize, Option<usize>) { |
55 | if self.done { |
56 | (0, Some(0)) |
57 | } else { |
58 | (0, self.iter.size_hint().1) |
59 | } |
60 | } |
61 | } |
62 | |
63 | impl<I, F> FusedIterator for TakeWhileInclusive<'_, I, F> |
64 | where |
65 | I: Iterator, |
66 | F: FnMut(&I::Item) -> bool |
67 | { |
68 | } |