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.
new(iter: &'a mut I, predicate: F) -> Self23     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 
next(&mut self) -> Option<Self::Item>41     fn next(&mut self) -> Option<Self::Item> {
42         if self.done {
43             None
44         } else {
45             self.iter.next().map(|item| {
46                 if !(self.predicate)(&item) {
47                     self.done = true;
48                 }
49                 item
50             })
51         }
52     }
53 
size_hint(&self) -> (usize, Option<usize>)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 }