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>
40        = I::Item<'a>
41    where
42        I: 'a,
43        P: 'a;
44
45    #[inline]
46    fn next(&mut self) -> Option<Self::Item<'_>> {
47        if self.done {
48            None
49        } else {
50            let item = self.iter.next()?;
51            if (self.predicate)(&item) {
52                Some(item)
53            } else {
54                self.done = true;
55                None
56            }
57        }
58    }
59
60    #[inline]
61    fn size_hint(&self) -> (usize, Option<usize>) {
62        if self.done {
63            (0, Some(0))
64        } else {
65            (0, self.iter.size_hint().1)
66        }
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use crate::{LendingIterator, ToLendingIterator};
73
74    fn identity(x: i32) -> i32 {
75        x
76    }
77
78    #[test]
79    fn take_while_basic() {
80        let result: Vec<_> = (0..10)
81            .into_lending()
82            .take_while(|&x| x < 5)
83            .map(identity)
84            .into_iter()
85            .collect();
86        assert_eq!(result, vec![0, 1, 2, 3, 4]);
87    }
88}