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};
64use crate::{
65 empty,
66 try_trait_v2::{ChangeOutputType, FromResidual, Residual, Try},
67 Empty, ExtendLender, IntoLender, Lend, Lender, Lending, TupleLend,
68};
69
70pub struct TryShunt<'this, L: Lender>
76where
77 for<'all> Lend<'all, L>: Try,
78{
79 lender: L,
80 residual: &'this mut Option<<Lend<'this, L> as Try>::Residual>,
81}
82impl<'lend, L: Lender> Lending<'lend> for TryShunt<'_, L>
83where
84 for<'all> Lend<'all, L>: Try,
85{
86 type Lend = <Lend<'lend, L> as Try>::Output;
87}
88impl<'this, L: Lender> Lender for TryShunt<'this, L>
89where
90 for<'all> Lend<'all, L>: Try,
91{
92 fn next(&mut self) -> Option<Lend<'_, Self>> {
93 if let Some(x) = self.lender.next() {
94 match x.branch() {
95 ControlFlow::Continue(x) => return Some(x),
96 ControlFlow::Break(x) => {
97 *self.residual = Some(unsafe {
99 core::mem::transmute::<<Lend<'_, L> as Try>::Residual, <Lend<'this, L> as Try>::Residual>(x)
100 });
101 }
102 }
103 }
104 None
105 }
106 fn size_hint(&self) -> (usize, Option<usize>) {
107 let (_, upper) = self.lender.size_hint();
108 (0, upper)
109 }
110}
111pub(crate) fn try_process<'a, L, F, U>(lender: L, mut f: F) -> ChangeOutputType<Lend<'a, L>, U>
112where
113 L: Lender + 'a,
114 for<'all> Lend<'all, L>: Try,
115 for<'all> <Lend<'all, L> as Try>::Residual: Residual<U>,
116 F: FnMut(TryShunt<'a, L>) -> U,
117{
118 let mut residual = None;
119 let reborrow = unsafe { &mut *(&mut residual as *mut _) };
121 let shunt = TryShunt { lender, residual: reborrow };
122 let value = f(shunt);
123 match residual {
124 Some(r) => FromResidual::from_residual(r),
125 None => Try::from_output(value),
126 }
127}
128
129pub struct FirstShunt<L>(PhantomData<L>);
131pub struct SecondShunt<L>(PhantomData<L>);
133impl<'lend, L: Lender> Lending<'lend> for FirstShunt<L>
134where
135 for<'all> Lend<'all, L>: TupleLend<'all>,
136{
137 type Lend = <Lend<'lend, L> as TupleLend<'lend>>::First;
138}
139impl<'lend, L: Lender> Lending<'lend> for SecondShunt<L>
140where
141 for<'all> Lend<'all, L>: TupleLend<'all>,
142{
143 type Lend = <Lend<'lend, L> as TupleLend<'lend>>::Second;
144}
145impl<L: Lender> IntoLender for FirstShunt<L>
146where
147 for<'all> Lend<'all, L>: TupleLend<'all>,
148{
149 type Lender = Empty<Self>;
150 fn into_lender(self) -> <Self as IntoLender>::Lender {
151 empty()
152 }
153}
154impl<L: Lender> IntoLender for SecondShunt<L>
155where
156 for<'all> Lend<'all, L>: TupleLend<'all>,
157{
158 type Lender = Empty<Self>;
159 fn into_lender(self) -> <Self as IntoLender>::Lender {
160 empty()
161 }
162}
163
164pub(crate) fn unzip<L, ExtA, ExtB>(mut lender: L) -> (ExtA, ExtB)
165where
166 L: Sized + Lender,
167 for<'all> Lend<'all, L>: TupleLend<'all>,
168 ExtA: Default + ExtendLender<FirstShunt<L>>,
169 ExtB: Default + ExtendLender<SecondShunt<L>>,
170{
171 let mut a = ExtA::default();
172 let mut b = ExtB::default();
173 let sz = lender.size_hint().0;
174 if sz > 0 {
175 a.extend_lender_reserve(sz);
176 b.extend_lender_reserve(sz);
177 }
178 while let Some(lend) = lender.next() {
179 let (x, y) = lend.tuple_lend();
180 a.extend_lender_one(x);
181 b.extend_lender_one(y);
182 }
183 (a, b)
184}