gat_lending_iterator/adapters/
skip_while.rs

1use crate::LendingIterator;
2use core::fmt;
3
4/// A lending iterator that that rejects elements while `predicate` returns `true`.
5#[derive(Clone)]
6#[must_use = "iterators are lazy and do nothing unless consumed"]
7pub struct SkipWhile<I, P> {
8    iter: I,
9    flag: bool,
10    predicate: P,
11}
12
13impl<I, P> SkipWhile<I, P> {
14    pub(crate) fn new(iter: I, predicate: P) -> Self {
15        Self {
16            iter,
17            flag: false,
18            predicate,
19        }
20    }
21}
22
23impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        f.debug_struct("TakeWhile")
26            .field("iter", &self.iter)
27            .field("flag", &self.flag)
28            .finish_non_exhaustive()
29    }
30}
31
32impl<I, P> LendingIterator for SkipWhile<I, P>
33where
34    I: LendingIterator,
35    P: for<'a> FnMut(&I::Item<'a>) -> bool,
36{
37    type Item<'a> = I::Item<'a> where Self: 'a;
38
39    #[inline]
40    fn next(&mut self) -> Option<Self::Item<'_>> {
41        if self.flag {
42            return self.iter.next()
43        }
44        loop {
45            // SAFETY: see https://docs.rs/polonius-the-crab/0.3.1/polonius_the_crab/#the-arcanemagic
46            let self_ = unsafe { &mut *(self as *mut Self) };
47            if let Some(item) = self_.iter.next() {
48                if !(self_.predicate)(&item) {
49                    self_.flag = true;
50                    return Some(item);
51                }
52            } else {
53                return None;
54            }
55        }
56    }
57
58    #[inline]
59    fn size_hint(&self) -> (usize, Option<usize>) {
60        let (_, upper) = self.iter.size_hint();
61        (0, upper) // can't know a lower bound, due to the predicate
62    }
63
64    // TODO: there's a `fold` optimization possible here,
65    // but for some reason the lifetimes don't type check
66}