gat_lending_iterator/adapters/
take_while.rs

1use crate::LendingIterator;
2use core::fmt;
3
4/// A lending iterator that yields items based on a predicate.
5///
6/// This iterator is fused.
7#[derive(Clone)]
8#[must_use = "iterators are lazy and do nothing unless consumed"]
9pub struct TakeWhile<I, P> {
10    iter: I,
11    predicate: P,
12    done: bool,
13}
14
15impl<I, P> TakeWhile<I, P> {
16    pub(crate) fn new(iter: I, predicate: P) -> Self {
17        Self {
18            iter,
19            predicate,
20            done: false,
21        }
22    }
23}
24
25impl<I: fmt::Debug, P> fmt::Debug for TakeWhile<I, P> {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        f.debug_struct("TakeWhile")
28            .field("iter", &self.iter)
29            .field("done", &self.done)
30            .finish_non_exhaustive()
31    }
32}
33
34impl<I, P> LendingIterator for TakeWhile<I, P>
35where
36    I: LendingIterator,
37    P: for<'a> FnMut(&I::Item<'a>) -> bool,
38{
39    type Item<'a> = I::Item<'a> where I: 'a, P: 'a;
40
41    #[inline]
42    fn next(&mut self) -> Option<Self::Item<'_>> {
43        if self.done {
44            None
45        } else {
46            let item = self.iter.next()?;
47            if (self.predicate)(&item) {
48                Some(item)
49            } else {
50                self.done = true;
51                None
52            }
53        }
54    }
55
56    #[inline]
57    fn size_hint(&self) -> (usize, Option<usize>) {
58        if self.done {
59            (0, Some(0))
60        } else {
61            (0, self.iter.size_hint().1)
62        }
63    }
64}