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