itertools/
take_while_inclusive.rs

1use core::iter::FusedIterator;
2use 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"]
11pub struct TakeWhileInclusive<'a, I: 'a, F> {
12    iter: &'a mut I,
13    predicate: F,
14    done: bool,
15}
16
17impl<'a, I, F> TakeWhileInclusive<'a, I, F>
18where
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
28impl<'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
34impl<'a, I, F> Iterator for TakeWhileInclusive<'a, I, F>
35where
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| {
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
63impl<I, F> FusedIterator for TakeWhileInclusive<'_, I, F>
64where
65    I: Iterator,
66    F: FnMut(&I::Item) -> bool
67{
68}