Skip to main content

lender/fallible_adapters/
fuse.rs

1use core::ops::ControlFlow;
2
3use crate::{
4    DoubleEndedFallibleLender, ExactSizeFallibleLender, FallibleLend, FallibleLender,
5    FallibleLending, Fuse, FusedFallibleLender,
6    try_trait_v2::{FromResidual, Try},
7};
8
9impl<L: FallibleLender> Fuse<L> {
10    #[inline(always)]
11    pub(crate) fn new_fallible(lender: L) -> Fuse<L> {
12        let _ = L::__check_covariance(crate::CovariantProof::new());
13        Fuse {
14            lender,
15            flag: false,
16        }
17    }
18}
19
20impl<'lend, L> FallibleLending<'lend> for Fuse<L>
21where
22    L: FallibleLender,
23{
24    type Lend = FallibleLend<'lend, L>;
25}
26
27impl<L> FallibleLender for Fuse<L>
28where
29    L: FallibleLender,
30{
31    type Error = L::Error;
32    // SAFETY: the lend is that of L
33    crate::unsafe_assume_covariance_fallible!();
34
35    #[inline]
36    fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
37        if !self.flag {
38            if let x @ Some(_) = self.lender.next()? {
39                return Ok(x);
40            }
41            self.flag = true;
42        }
43        Ok(None)
44    }
45
46    #[inline]
47    fn nth(&mut self, n: usize) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
48        if !self.flag {
49            if let x @ Some(_) = self.lender.nth(n)? {
50                return Ok(x);
51            }
52            self.flag = true;
53        }
54        Ok(None)
55    }
56
57    #[inline]
58    fn last(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error>
59    where
60        Self: Sized,
61    {
62        if !self.flag {
63            if let x @ Some(_) = self.lender.last()? {
64                return Ok(x);
65            }
66            self.flag = true;
67        }
68        Ok(None)
69    }
70
71    #[inline]
72    fn count(self) -> Result<usize, Self::Error> {
73        if !self.flag {
74            self.lender.count()
75        } else {
76            Ok(0)
77        }
78    }
79
80    #[inline]
81    fn size_hint(&self) -> (usize, Option<usize>) {
82        if !self.flag {
83            self.lender.size_hint()
84        } else {
85            (0, Some(0))
86        }
87    }
88
89    #[inline]
90    fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> Result<R, Self::Error>
91    where
92        F: FnMut(Acc, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
93        R: Try<Output = Acc>,
94    {
95        if !self.flag {
96            acc = match self.lender.try_fold(acc, &mut f)?.branch() {
97                ControlFlow::Continue(x) => x,
98                ControlFlow::Break(x) => return Ok(FromResidual::from_residual(x)),
99            };
100            self.flag = true;
101        }
102        Ok(Try::from_output(acc))
103    }
104
105    #[inline]
106    fn fold<B, F>(self, init: B, mut f: F) -> Result<B, Self::Error>
107    where
108        Self: Sized,
109        F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
110    {
111        if !self.flag {
112            self.lender.fold(init, &mut f)
113        } else {
114            Ok(init)
115        }
116    }
117
118    #[inline]
119    fn find<P>(&mut self, mut predicate: P) -> Result<Option<FallibleLend<'_, Self>>, Self::Error>
120    where
121        P: FnMut(&FallibleLend<'_, Self>) -> Result<bool, Self::Error>,
122    {
123        if !self.flag {
124            if let x @ Some(_) = self.lender.find(&mut predicate)? {
125                return Ok(x);
126            }
127            self.flag = true;
128        }
129        Ok(None)
130    }
131}
132
133impl<L> DoubleEndedFallibleLender for Fuse<L>
134where
135    L: DoubleEndedFallibleLender,
136{
137    #[inline]
138    fn next_back(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
139        if !self.flag {
140            if let x @ Some(_) = self.lender.next_back()? {
141                return Ok(x);
142            }
143            self.flag = true;
144        }
145        Ok(None)
146    }
147
148    #[inline]
149    fn nth_back(&mut self, n: usize) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
150        if !self.flag {
151            if let x @ Some(_) = self.lender.nth_back(n)? {
152                return Ok(x);
153            }
154            self.flag = true;
155        }
156        Ok(None)
157    }
158
159    #[inline]
160    fn try_rfold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> Result<R, Self::Error>
161    where
162        Self: Sized,
163        F: FnMut(Acc, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
164        R: Try<Output = Acc>,
165    {
166        if !self.flag {
167            acc = match self.lender.try_rfold(acc, &mut f)?.branch() {
168                ControlFlow::Continue(x) => x,
169                ControlFlow::Break(x) => return Ok(FromResidual::from_residual(x)),
170            };
171            self.flag = true;
172        }
173        Ok(Try::from_output(acc))
174    }
175
176    #[inline]
177    fn rfold<B, F>(self, init: B, mut f: F) -> Result<B, Self::Error>
178    where
179        Self: Sized,
180        F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
181    {
182        if !self.flag {
183            self.lender.rfold(init, &mut f)
184        } else {
185            Ok(init)
186        }
187    }
188
189    #[inline]
190    fn rfind<P>(&mut self, mut predicate: P) -> Result<Option<FallibleLend<'_, Self>>, Self::Error>
191    where
192        Self: Sized,
193        P: FnMut(&FallibleLend<'_, Self>) -> Result<bool, Self::Error>,
194    {
195        if !self.flag {
196            if let x @ Some(_) = self.lender.rfind(&mut predicate)? {
197                return Ok(x);
198            }
199            self.flag = true;
200        }
201        Ok(None)
202    }
203}
204
205impl<L> ExactSizeFallibleLender for Fuse<L>
206where
207    L: ExactSizeFallibleLender,
208{
209    #[inline]
210    fn len(&self) -> usize {
211        if self.flag { 0 } else { self.lender.len() }
212    }
213
214    #[inline]
215    fn is_empty(&self) -> bool {
216        self.flag || self.lender.is_empty()
217    }
218}
219
220impl<L> FusedFallibleLender for Fuse<L> where L: FallibleLender {}