1use core::{marker::PhantomData, ops::ControlFlow};
2
3mod chain;
4mod chunk;
5mod chunky;
6mod cloned;
7mod copied;
8mod cycle;
9mod enumerate;
10mod filter;
11mod filter_map;
12mod flatten;
13mod fuse;
14mod inspect;
15mod intersperse;
16mod iter;
17mod map;
18mod map_into_iter;
19mod map_while;
20mod mutate;
21mod owned;
22mod peekable;
23mod rev;
24mod scan;
25mod skip;
26mod skip_while;
27mod step_by;
28mod take;
29mod take_while;
30mod zip;
31
32pub use intersperse::{Intersperse, IntersperseWith};
33pub use zip::zip;
34
35pub use self::{
36 chain::Chain,
37 chunk::Chunk,
38 chunky::Chunky,
39 cloned::Cloned,
40 copied::Copied,
41 cycle::Cycle,
42 enumerate::Enumerate,
43 filter::Filter,
44 filter_map::FilterMap,
45 flatten::{FlatMap, Flatten},
46 fuse::Fuse,
47 inspect::Inspect,
48 iter::Iter,
49 map::Map,
50 map_into_iter::MapIntoIter,
51 map_while::MapWhile,
52 mutate::Mutate,
53 owned::Owned,
54 peekable::Peekable,
55 rev::Rev,
56 scan::Scan,
57 skip::Skip,
58 skip_while::SkipWhile,
59 step_by::StepBy,
60 take::Take,
61 take_while::TakeWhile,
62 zip::Zip,
63};
64
65use crate::{
66 Empty, ExtendLender, FallibleEmpty, FallibleLend, FallibleLender, FallibleLending,
67 IntoFallibleLender, IntoLender, Lend, Lender, Lending, NonFallibleAdapter, TupleLend, empty,
68 fallible_empty,
69 try_trait_v2::{ChangeOutputType, FromResidual, Residual, Try},
70};
71
72#[doc(hidden)]
81pub struct TryShunt<'this, L: Lender>
82where
83 for<'all> Lend<'all, L>: Try,
84{
85 lender: L,
86 residual: &'this mut Option<<Lend<'this, L> as Try>::Residual>,
87}
88
89impl<'lend, L: Lender> Lending<'lend> for TryShunt<'_, L>
90where
91 for<'all> Lend<'all, L>: Try,
92{
93 type Lend = <Lend<'lend, L> as Try>::Output;
94}
95
96impl<'this, L: Lender> Lender for TryShunt<'this, L>
97where
98 for<'all> Lend<'all, L>: Try,
99{
100 crate::unsafe_assume_covariance!();
102 #[inline]
103 fn next(&mut self) -> Option<Lend<'_, Self>> {
104 if self.residual.is_some() {
105 return None;
106 }
107 if let Some(x) = self.lender.next() {
108 match x.branch() {
109 ControlFlow::Continue(x) => return Some(x),
110 ControlFlow::Break(x) => {
111 *self.residual = Some(unsafe {
113 core::mem::transmute::<
114 <Lend<'_, L> as Try>::Residual,
115 <Lend<'this, L> as Try>::Residual,
116 >(x)
117 });
118 }
119 }
120 }
121 None
122 }
123
124 #[inline]
125 fn size_hint(&self) -> (usize, Option<usize>) {
126 let (_, upper) = self.lender.size_hint();
127 (0, upper)
128 }
129}
130
131#[inline]
132pub(crate) fn try_process<'a, L, F, U>(lender: L, mut f: F) -> ChangeOutputType<Lend<'a, L>, U>
133where
134 L: Lender + 'a,
135 for<'all> Lend<'all, L>: Try,
136 for<'all> <Lend<'all, L> as Try>::Residual: Residual<U>,
137 for<'all> F: FnMut(TryShunt<'all, L>) -> U,
138{
139 let _ = L::__check_covariance(crate::CovariantProof::new());
140 let mut residual = None;
141 #[allow(clippy::deref_addrof)]
143 let reborrow = unsafe { &mut *(&raw mut residual) };
144 let shunt = TryShunt {
145 lender,
146 residual: reborrow,
147 };
148 let value = f(shunt);
149 match residual {
150 Some(r) => FromResidual::from_residual(r),
151 None => Try::from_output(value),
152 }
153}
154
155#[doc(hidden)]
156pub struct FirstShunt<L>(PhantomData<L>);
159
160#[doc(hidden)]
161pub struct SecondShunt<L>(PhantomData<L>);
164
165impl<'lend, L: Lender> Lending<'lend> for FirstShunt<L>
166where
167 for<'all> Lend<'all, L>: TupleLend<'all>,
168{
169 type Lend = <Lend<'lend, L> as TupleLend<'lend>>::First;
170}
171
172impl<'lend, L: Lender> Lending<'lend> for SecondShunt<L>
173where
174 for<'all> Lend<'all, L>: TupleLend<'all>,
175{
176 type Lend = <Lend<'lend, L> as TupleLend<'lend>>::Second;
177}
178
179impl<L: Lender> IntoLender for FirstShunt<L>
180where
181 for<'all> Lend<'all, L>: TupleLend<'all>,
182{
183 type Lender = Empty<Self>;
184 #[inline(always)]
185 fn into_lender(self) -> <Self as IntoLender>::Lender {
186 empty()
187 }
188}
189
190impl<L: Lender> IntoLender for SecondShunt<L>
191where
192 for<'all> Lend<'all, L>: TupleLend<'all>,
193{
194 type Lender = Empty<Self>;
195 #[inline(always)]
196 fn into_lender(self) -> <Self as IntoLender>::Lender {
197 empty()
198 }
199}
200
201impl<'lend, L: FallibleLender> FallibleLending<'lend> for FirstShunt<L>
202where
203 for<'all> FallibleLend<'all, L>: TupleLend<'all>,
204{
205 type Lend = <FallibleLend<'lend, L> as TupleLend<'lend>>::First;
206}
207
208impl<'lend, L: FallibleLender> FallibleLending<'lend> for SecondShunt<L>
209where
210 for<'all> FallibleLend<'all, L>: TupleLend<'all>,
211{
212 type Lend = <FallibleLend<'lend, L> as TupleLend<'lend>>::Second;
213}
214
215impl<L: FallibleLender> IntoFallibleLender for FirstShunt<L>
216where
217 for<'all> FallibleLend<'all, L>: TupleLend<'all>,
218{
219 type Error = L::Error;
220
221 type FallibleLender = FallibleEmpty<Self, L::Error>;
222 #[inline(always)]
223 fn into_fallible_lender(self) -> <Self as IntoFallibleLender>::FallibleLender {
224 fallible_empty()
225 }
226}
227
228impl<L: FallibleLender> IntoFallibleLender for SecondShunt<L>
229where
230 for<'all> FallibleLend<'all, L>: TupleLend<'all>,
231{
232 type Error = L::Error;
233
234 type FallibleLender = FallibleEmpty<Self, L::Error>;
235 #[inline(always)]
236 fn into_fallible_lender(self) -> <Self as IntoFallibleLender>::FallibleLender {
237 fallible_empty()
238 }
239}
240
241#[inline]
242pub(crate) fn unzip<L, ExtA, ExtB>(mut lender: L) -> (ExtA, ExtB)
243where
244 L: Sized + Lender,
245 for<'all> Lend<'all, L>: TupleLend<'all>,
246 ExtA: Default + ExtendLender<FirstShunt<L>>,
247 ExtB: Default + ExtendLender<SecondShunt<L>>,
248{
249 let mut a = ExtA::default();
250 let mut b = ExtB::default();
251 let sz = lender.size_hint().0;
252 if sz > 0 {
253 a.extend_lender_reserve(sz);
254 b.extend_lender_reserve(sz);
255 }
256 while let Some(lend) = lender.next() {
257 let (x, y) = lend.tuple_lend();
258 a.extend_lender_one(x);
259 b.extend_lender_one(y);
260 }
261 (a, b)
262}
263
264#[inline]
265pub(crate) fn fallible_unzip<L, ExtA, ExtB>(mut lender: L) -> Result<(ExtA, ExtB), L::Error>
266where
267 L: Sized + FallibleLender,
268 for<'all> FallibleLend<'all, L>: TupleLend<'all>,
269 ExtA: Default
270 + for<'this> ExtendLender<
271 NonFallibleAdapter<'this, <FirstShunt<L> as IntoFallibleLender>::FallibleLender>,
272 >,
273 ExtB: Default
274 + for<'this> ExtendLender<
275 NonFallibleAdapter<'this, <SecondShunt<L> as IntoFallibleLender>::FallibleLender>,
276 >,
277{
278 let mut a = ExtA::default();
279 let mut b = ExtB::default();
280 let sz = lender.size_hint().0;
281 if sz > 0 {
282 a.extend_lender_reserve(sz);
283 b.extend_lender_reserve(sz);
284 }
285 while let Some(lend) = lender.next()? {
286 let (x, y) = lend.tuple_lend();
287 a.extend_lender_one(x);
288 b.extend_lender_one(y);
289 }
290 Ok((a, b))
291}