lender/fallible_adapters/
cycle.rs1use crate::{
2 Cycle, FallibleLend, FallibleLender, FallibleLending, FusedFallibleLender,
3 try_trait_v2::{FromResidual, Try},
4};
5use core::{num::NonZeroUsize, ops::ControlFlow};
6
7impl<L: Clone + FallibleLender> Cycle<L> {
8 #[inline]
9 pub(crate) fn new_fallible(lender: L) -> Cycle<L> {
10 let _ = L::__check_covariance(crate::CovariantProof::new());
11 Cycle {
12 orig: lender.clone(),
13 lender,
14 }
15 }
16}
17
18impl<'lend, L> FallibleLending<'lend> for Cycle<L>
19where
20 L: Clone + FallibleLender,
21{
22 type Lend = FallibleLend<'lend, L>;
23}
24
25impl<L> FallibleLender for Cycle<L>
26where
27 L: Clone + FallibleLender,
28{
29 type Error = L::Error;
30 crate::unsafe_assume_covariance_fallible!();
32
33 #[inline]
34 fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
35 #[allow(clippy::deref_addrof)]
37 let reborrow = unsafe { &mut *(&raw mut *self) };
38 if let x @ Some(_) = reborrow.lender.next()? {
39 return Ok(x);
40 }
41 self.lender = self.orig.clone();
42 self.lender.next()
43 }
44
45 #[inline]
46 fn size_hint(&self) -> (usize, Option<usize>) {
47 match self.orig.size_hint() {
48 h @ (0, Some(0)) => h,
49 (0, _) => (0, None),
50 _ => (usize::MAX, None),
51 }
52 }
53
54 #[inline]
55 fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
56 where
57 Self: Sized,
58 F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
59 R: Try<Output = B>,
60 {
61 let mut acc = init;
62 acc = match self.lender.try_fold(acc, &mut f)?.branch() {
63 ControlFlow::Break(x) => return Ok(FromResidual::from_residual(x)),
64 ControlFlow::Continue(x) => x,
65 };
66 self.lender = self.orig.clone();
67 let mut empty = true;
68 acc = match self
69 .lender
70 .try_fold(acc, |acc, x| {
71 empty = false;
72 f(acc, x)
73 })?
74 .branch()
75 {
76 ControlFlow::Break(x) => return Ok(FromResidual::from_residual(x)),
77 ControlFlow::Continue(x) => x,
78 };
79 if empty {
80 return Ok(Try::from_output(acc));
81 }
82 loop {
83 self.lender = self.orig.clone();
84 acc = match self.lender.try_fold(acc, &mut f)?.branch() {
85 ControlFlow::Break(x) => return Ok(FromResidual::from_residual(x)),
86 ControlFlow::Continue(x) => x,
87 };
88 }
89 }
90
91 #[inline]
92 fn advance_by(&mut self, n: usize) -> Result<Result<(), NonZeroUsize>, Self::Error> {
93 let mut n = match self.lender.advance_by(n)? {
94 Ok(()) => return Ok(Ok(())),
95 Err(rem) => rem.get(),
96 };
97
98 while n > 0 {
99 self.lender = self.orig.clone();
100 n = match self.lender.advance_by(n)? {
101 Ok(()) => return Ok(Ok(())),
102 Err(rem) if rem.get() == n => return Ok(Err(rem)),
103 Err(rem) => rem.get(),
104 };
105 }
106
107 Ok(Ok(()))
108 }
109}
110
111impl<L> FusedFallibleLender for Cycle<L> where L: Clone + FallibleLender {}