lender/adapters/
skip_while.rs

1use core::{fmt, ops::ControlFlow};
2
3use crate::{try_trait_v2::Try, FusedLender, Lend, Lender, Lending};
4#[derive(Clone)]
5#[must_use = "lenders are lazy and do nothing unless consumed"]
6pub struct SkipWhile<L, P> {
7    lender: L,
8    flag: bool,
9    predicate: P,
10}
11impl<L, P> SkipWhile<L, P> {
12    pub(crate) fn new(lender: L, predicate: P) -> SkipWhile<L, P> {
13        SkipWhile { lender, flag: false, predicate }
14    }
15    pub fn into_inner(self) -> L {
16        self.lender
17    }
18    pub fn into_parts(self) -> (L, P) {
19        (self.lender, self.predicate)
20    }
21}
22impl<L: fmt::Debug, P> fmt::Debug for SkipWhile<L, P> {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        f.debug_struct("SkipWhile").field("lender", &self.lender).finish()
25    }
26}
27impl<'lend, L, P> Lending<'lend> for SkipWhile<L, P>
28where
29    P: FnMut(&Lend<'lend, L>) -> bool,
30    L: Lender,
31{
32    type Lend = Lend<'lend, L>;
33}
34impl<L, P> Lender for SkipWhile<L, P>
35where
36    P: FnMut(&Lend<'_, L>) -> bool,
37    L: Lender,
38{
39    #[inline]
40    fn next(&mut self) -> Option<Lend<'_, Self>> {
41        let flag = &mut self.flag;
42        let predicate = &mut self.predicate;
43        self.lender.find(move |x| {
44            if *flag || !(predicate)(x) {
45                *flag = true;
46                true
47            } else {
48                false
49            }
50        })
51    }
52    #[inline]
53    fn size_hint(&self) -> (usize, Option<usize>) {
54        let (_, upper) = self.lender.size_hint();
55        (0, upper)
56    }
57    #[inline]
58    fn try_fold<B, F, R>(&mut self, mut init: B, mut f: F) -> R
59    where
60        Self: Sized,
61        F: FnMut(B, Lend<'_, Self>) -> R,
62        R: Try<Output = B>,
63    {
64        if !self.flag {
65            match self.next() {
66                Some(x) => {
67                    init = match f(init, x).branch() {
68                        ControlFlow::Break(x) => return R::from_residual(x),
69                        ControlFlow::Continue(x) => x,
70                    }
71                }
72                None => return R::from_output(init),
73            }
74        }
75        self.lender.try_fold(init, f)
76    }
77    #[inline]
78    fn fold<B, F>(mut self, mut init: B, mut f: F) -> B
79    where
80        Self: Sized,
81        F: FnMut(B, Lend<'_, Self>) -> B,
82    {
83        if !self.flag {
84            match self.next() {
85                Some(x) => init = f(init, x),
86                None => return init,
87            }
88        }
89        self.lender.fold(init, f)
90    }
91}
92impl<L, P> FusedLender for SkipWhile<L, P>
93where
94    P: FnMut(&Lend<'_, L>) -> bool,
95    L: FusedLender,
96{
97}