lender/fallible_adapters/
intersperse.rs1use core::fmt;
2
3use crate::{FallibleLend, FallibleLender, FallibleLending, FalliblePeekable, FusedFallibleLender};
4
5#[must_use = "lenders are lazy and do nothing unless consumed"]
14pub struct Intersperse<'this, L>
15where
16 for<'all> FallibleLend<'all, L>: Clone,
17 L: FallibleLender,
18{
19 separator: FallibleLend<'this, L>,
21 needs_sep: bool,
22 lender: FalliblePeekable<'this, L>,
23}
24
25impl<'this, L> Intersperse<'this, L>
26where
27 for<'all> FallibleLend<'all, L>: Clone,
28 L: FallibleLender,
29{
30 #[inline]
31 pub(crate) fn new(lender: L, separator: FallibleLend<'this, L>) -> Self {
32 crate::__check_fallible_lender_covariance::<L>();
33 Self {
34 separator,
35 needs_sep: false,
36 lender: lender.peekable(),
37 }
38 }
39
40 #[inline]
42 pub fn into_inner(self) -> L {
43 self.lender.into_inner()
44 }
45
46 #[inline]
48 pub fn into_parts(self) -> (L, FallibleLend<'this, L>) {
49 (self.lender.into_inner(), self.separator)
50 }
51}
52
53impl<L: fmt::Debug> fmt::Debug for Intersperse<'_, L>
54where
55 for<'all> FallibleLend<'all, L>: Clone + fmt::Debug,
56 L: FallibleLender,
57{
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 f.debug_struct("Intersperse")
60 .field("lender", &self.lender)
61 .field("separator", &self.separator)
62 .field("needs_sep", &self.needs_sep)
63 .finish()
64 }
65}
66
67impl<'lend, L> FallibleLending<'lend> for Intersperse<'_, L>
68where
69 for<'all> FallibleLend<'all, L>: Clone,
70 L: FallibleLender,
71{
72 type Lend = FallibleLend<'lend, L>;
73}
74
75impl<'this, L> FallibleLender for Intersperse<'this, L>
76where
77 for<'all> FallibleLend<'all, L>: Clone,
78 L: FallibleLender,
79{
80 type Error = L::Error;
81 crate::unsafe_assume_covariance_fallible!();
83
84 #[inline]
85 fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
86 if self.needs_sep && self.lender.peek()?.is_some() {
87 self.needs_sep = false;
88 Ok(Some(
89 unsafe {
91 core::mem::transmute::<FallibleLend<'this, Self>, FallibleLend<'_, Self>>(
92 self.separator.clone(),
93 )
94 },
95 ))
96 } else {
97 self.needs_sep = true;
98 self.lender.next()
99 }
100 }
101
102 #[inline]
103 fn fold<B, F>(mut self, init: B, mut f: F) -> Result<B, Self::Error>
104 where
105 Self: Sized,
106 F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
107 {
108 let mut acc = init;
109 if !self.needs_sep {
110 if let Some(x) = self.lender.next()? {
111 acc = f(acc, x)?;
112 } else {
113 return Ok(acc);
114 }
115 }
116 self.lender.fold(acc, |mut acc, x| {
117 acc = f(acc, self.separator.clone())?;
118 acc = f(acc, x)?;
119 Ok(acc)
120 })
121 }
122
123 #[inline]
124 fn size_hint(&self) -> (usize, Option<usize>) {
125 intersperse_size_hint(&self.lender, self.needs_sep)
126 }
127}
128
129#[must_use = "lenders are lazy and do nothing unless consumed"]
138pub struct IntersperseWith<'this, L, G>
139where
140 L: FallibleLender,
141{
142 separator: G,
143 lender: FalliblePeekable<'this, L>,
144 needs_sep: bool,
145}
146
147impl<'this, L, G> IntersperseWith<'this, L, G>
148where
149 L: FallibleLender,
150 G: FnMut() -> Result<FallibleLend<'this, L>, L::Error>,
151{
152 #[inline]
153 pub(crate) fn new(lender: L, separator: G) -> Self {
154 crate::__check_fallible_lender_covariance::<L>();
155 Self {
156 lender: FalliblePeekable::new(lender),
157 separator,
158 needs_sep: false,
159 }
160 }
161
162 #[inline]
164 pub fn into_inner(self) -> L {
165 self.lender.into_inner()
166 }
167
168 #[inline]
170 pub fn into_parts(self) -> (L, G) {
171 (self.lender.into_inner(), self.separator)
172 }
173}
174
175impl<L: fmt::Debug, G> fmt::Debug for IntersperseWith<'_, L, G>
176where
177 L: FallibleLender,
178 for<'all> FallibleLend<'all, L>: fmt::Debug,
179{
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 f.debug_struct("IntersperseWith")
182 .field("lender", &self.lender)
183 .field("needs_sep", &self.needs_sep)
184 .finish_non_exhaustive()
185 }
186}
187
188impl<'lend, 'this, L, G> FallibleLending<'lend> for IntersperseWith<'this, L, G>
189where
190 L: FallibleLender,
191 G: FnMut() -> Result<FallibleLend<'this, L>, L::Error>,
192{
193 type Lend = FallibleLend<'lend, L>;
194}
195
196impl<'this, L, G> FallibleLender for IntersperseWith<'this, L, G>
197where
198 L: FallibleLender,
199 G: FnMut() -> Result<FallibleLend<'this, L>, L::Error>,
200{
201 type Error = L::Error;
202 crate::unsafe_assume_covariance_fallible!();
204
205 #[inline]
206 fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
207 if self.needs_sep && self.lender.peek()?.is_some() {
208 self.needs_sep = false;
209 let separator = (self.separator)()?;
210 Ok(Some(
211 unsafe {
213 core::mem::transmute::<FallibleLend<'this, L>, FallibleLend<'_, L>>(separator)
214 },
215 ))
216 } else {
217 self.needs_sep = true;
218 self.lender.next()
219 }
220 }
221
222 #[inline]
223 fn fold<B, F>(mut self, init: B, mut f: F) -> Result<B, Self::Error>
224 where
225 Self: Sized,
226 F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
227 {
228 let mut acc = init;
229 if !self.needs_sep {
230 if let Some(x) = self.lender.next()? {
231 acc = f(acc, x)?;
232 } else {
233 return Ok(acc);
234 }
235 }
236 self.lender.fold(acc, |mut acc, x| {
237 acc = f(acc, (self.separator)()?)?;
238 acc = f(acc, x)?;
239 Ok(acc)
240 })
241 }
242
243 #[inline]
244 fn size_hint(&self) -> (usize, Option<usize>) {
245 intersperse_size_hint(&self.lender, self.needs_sep)
246 }
247}
248
249#[inline]
250fn intersperse_size_hint<L>(lender: &L, needs_sep: bool) -> (usize, Option<usize>)
251where
252 L: FallibleLender,
253{
254 let (lo, hi) = lender.size_hint();
255 let next_is_elem = !needs_sep;
256 (
257 lo.saturating_sub(next_is_elem as usize).saturating_add(lo),
258 hi.and_then(|hi| hi.saturating_sub(next_is_elem as usize).checked_add(hi)),
259 )
260}
261
262impl<'this, L> FusedFallibleLender for Intersperse<'this, L>
263where
264 for<'all> FallibleLend<'all, L>: Clone,
265 L: FusedFallibleLender,
266{
267}
268
269impl<'this, L, G> FusedFallibleLender for IntersperseWith<'this, L, G>
270where
271 L: FusedFallibleLender,
272 G: FnMut() -> Result<FallibleLend<'this, L>, L::Error>,
273{
274}