lender/fallible_adapters/
convert.rs1use core::{marker::PhantomData, ops::ControlFlow};
2
3use stable_try_trait_v2::Try;
4
5use crate::{
6 DoubleEndedFallibleLender, DoubleEndedLender, ExactSizeFallibleLender, ExactSizeLender,
7 FallibleLend, FallibleLender, FallibleLending, FusedFallibleLender, FusedLender, ImplBound,
8 Lender, Lending, Ref,
9};
10
11trait LendingResult<'lend, E, __ImplBound: ImplBound = Ref<'lend, Self>>:
12 Lending<'lend, __ImplBound, Lend = Result<Self::Item, E>>
13{
14 type Item: 'lend;
15}
16
17impl<'a, Bound, T, E, I> LendingResult<'a, E, Bound> for I
18where
19 Bound: ImplBound,
20 T: 'a,
21 I: Lending<'a, Bound, Lend = Result<T, E>>,
22{
23 type Item = T;
24}
25
26trait LenderResult<E>: Lender + for<'all> LendingResult<'all, E> {}
27
28impl<E, I> LenderResult<E> for I where I: Lender + for<'all> LendingResult<'all, E> {}
29
30#[derive(Clone, Debug)]
35#[repr(transparent)]
36#[must_use = "lenders are lazy and do nothing unless consumed"]
37pub struct Convert<E, I> {
38 iter: I,
39 _marker: PhantomData<fn() -> E>,
40}
41
42impl<E, I: crate::Lender> Convert<E, I> {
43 #[inline(always)]
44 pub(crate) fn new(iter: I) -> Self {
45 let _ = <I as crate::Lender>::__check_covariance(crate::CovariantProof::new());
46 Self {
47 iter,
48 _marker: PhantomData,
49 }
50 }
51
52 #[inline(always)]
54 pub fn into_inner(self) -> I {
55 self.iter
56 }
57}
58
59impl<'lend, E, I> FallibleLending<'lend> for Convert<E, I>
60where
61 I: LendingResult<'lend, E>,
62{
63 type Lend = <<I as Lending<'lend>>::Lend as Try>::Output;
64}
65
66impl<E, I> FallibleLender for Convert<E, I>
67where
68 I: LenderResult<E>,
69{
70 type Error = E;
71 crate::unsafe_assume_covariance_fallible!();
73
74 #[inline]
75 fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, E> {
76 match self.iter.next() {
77 Some(Ok(i)) => Ok(Some(i)),
78 Some(Err(e)) => Err(e),
79 None => Ok(None),
80 }
81 }
82
83 #[inline(always)]
84 fn size_hint(&self) -> (usize, Option<usize>) {
85 self.iter.size_hint()
86 }
87
88 #[inline]
89 fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
90 where
91 Self: Sized,
92 F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
93 R: Try<Output = B>,
94 {
95 match self.iter.try_fold(init, |acc, item| match item {
96 Ok(v) => super::try_fold_with(f(acc, v)),
97 Err(e) => ControlFlow::Break(Err(e)),
98 }) {
99 ControlFlow::Continue(acc) => Ok(R::from_output(acc)),
100 ControlFlow::Break(r) => r,
101 }
102 }
103
104 #[inline]
105 fn fold<B, F>(mut self, init: B, mut f: F) -> Result<B, Self::Error>
106 where
107 Self: Sized,
108 F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
109 {
110 match self.iter.try_fold(init, |acc, item| match item {
113 Ok(v) => match f(acc, v) {
114 Ok(b) => ControlFlow::Continue(b),
115 Err(e) => ControlFlow::Break(e),
116 },
117 Err(e) => ControlFlow::Break(e),
118 }) {
119 ControlFlow::Continue(acc) => Ok(acc),
120 ControlFlow::Break(e) => Err(e),
121 }
122 }
123}
124
125impl<E, I> DoubleEndedFallibleLender for Convert<E, I>
126where
127 I: DoubleEndedLender + LenderResult<E>,
128{
129 #[inline]
130 fn next_back(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
131 match self.iter.next_back() {
132 Some(Ok(i)) => Ok(Some(i)),
133 Some(Err(e)) => Err(e),
134 None => Ok(None),
135 }
136 }
137
138 #[inline]
139 fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
140 where
141 Self: Sized,
142 F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
143 R: Try<Output = B>,
144 {
145 match self.iter.try_rfold(init, |acc, item| match item {
146 Ok(v) => super::try_fold_with(f(acc, v)),
147 Err(e) => ControlFlow::Break(Err(e)),
148 }) {
149 ControlFlow::Continue(acc) => Ok(R::from_output(acc)),
150 ControlFlow::Break(r) => r,
151 }
152 }
153
154 #[inline]
155 fn rfold<B, F>(mut self, init: B, mut f: F) -> Result<B, Self::Error>
156 where
157 Self: Sized,
158 F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
159 {
160 match self.iter.try_rfold(init, |acc, item| match item {
161 Ok(v) => match f(acc, v) {
162 Ok(b) => ControlFlow::Continue(b),
163 Err(e) => ControlFlow::Break(e),
164 },
165 Err(e) => ControlFlow::Break(e),
166 }) {
167 ControlFlow::Continue(acc) => Ok(acc),
168 ControlFlow::Break(e) => Err(e),
169 }
170 }
171}
172
173impl<E, I> ExactSizeFallibleLender for Convert<E, I>
174where
175 I: ExactSizeLender + LenderResult<E>,
176{
177 #[inline(always)]
178 fn len(&self) -> usize {
179 self.iter.len()
180 }
181
182 #[inline(always)]
183 fn is_empty(&self) -> bool {
184 self.iter.is_empty()
185 }
186}
187
188impl<E, I> FusedFallibleLender for Convert<E, I> where I: FusedLender + LenderResult<E> {}