1use std::{future::Future, fmt::Debug};
2
3use super::peekable::Peekable;
4use crate::AsyncIterator;
5
6#[must_use = "iterators are lazy and do nothing unless consumed"]
7#[derive(Debug, Clone)]
8pub struct Intersperse<I: AsyncIterator>
9where
10 I::Item: Clone,
11{
12 separator: I::Item,
13 iter: Peekable<I>,
14 needs_sep: bool,
15}
16
17impl<I: AsyncIterator> Intersperse<I>
18where
19 I::Item: Clone,
20{
21 pub fn new(iter: I, separator: I::Item) -> Self {
22 Self {
23 iter: iter.peekable(),
24 separator,
25 needs_sep: false,
26 }
27 }
28}
29
30impl<I> AsyncIterator for Intersperse<I>
31where
32 I: AsyncIterator,
33 I::Item: Clone,
34{
35 type Item = I::Item;
36
37 #[inline]
38 async fn next(&mut self) -> Option<I::Item> {
39 if self.needs_sep && self.iter.peek().await.is_some() {
40 self.needs_sep = false;
41 Some(self.separator.clone())
42 } else {
43 self.needs_sep = true;
44 self.iter.next().await
45 }
46 }
47
48 #[inline]
49 fn size_hint(&self) -> (usize, Option<usize>) {
50 intersperse_size_hint(&self.iter, self.needs_sep)
51 }
52}
53
54#[must_use = "iterators are lazy and do nothing unless consumed"]
55pub struct IntersperseWith<I, G>
56where
57 I: AsyncIterator,
58{
59 separator: G,
60 iter: Peekable<I>,
61 needs_sep: bool,
62}
63
64impl<I: AsyncIterator + Debug, G> Debug for IntersperseWith<I, G>
65where
66 I::Item: Debug
67{
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 f.debug_struct("IntersperseWith")
70 .field("needs_sep", &self.needs_sep)
71 .field("iter", &self.iter)
72 .finish()
73 }
74}
75
76impl<I: AsyncIterator + Clone, G: Clone> std::clone::Clone for IntersperseWith<I, G>
77where
78 I::Item: Clone,
79{
80 fn clone(&self) -> Self {
81 Self {
82 separator: self.separator.clone(),
83 iter: self.iter.clone(),
84 needs_sep: self.needs_sep,
85 }
86 }
87
88 fn clone_from(&mut self, source: &Self) {
89 self.separator = source.separator.clone();
90 self.iter = source.iter.clone();
91 self.needs_sep = source.needs_sep;
92 }
93}
94
95impl<I, G> IntersperseWith<I, G>
96where
97 I: AsyncIterator,
98 G: FnMut() -> I::Item,
99{
100 pub fn new(iter: I, separator: G) -> Self {
101 Self {
102 iter: iter.peekable(),
103 separator,
104 needs_sep: false,
105 }
106 }
107}
108
109impl<I, G> AsyncIterator for IntersperseWith<I, G>
110where
111 I: AsyncIterator,
112 G: FnMut() -> I::Item,
113{
114 type Item = I::Item;
115
116 #[inline]
117 async fn next(&mut self) -> Option<I::Item> {
118 if self.needs_sep && self.iter.peek().await.is_some() {
119 self.needs_sep = false;
120 Some((self.separator)())
121 } else {
122 self.needs_sep = true;
123 self.iter.next().await
124 }
125 }
126
127 #[inline]
128 fn size_hint(&self) -> (usize, Option<usize>) {
129 intersperse_size_hint(&self.iter, self.needs_sep)
130 }
131}
132
133#[must_use = "iterators are lazy and do nothing unless consumed"]
134pub struct AsyncIntersperseWith<I, G>
135where
136 I: AsyncIterator,
137{
138 separator: G,
139 iter: Peekable<I>,
140 needs_sep: bool,
141}
142
143impl<I: AsyncIterator + Debug, G> Debug for AsyncIntersperseWith<I, G>
144where
145 I::Item: Debug
146{
147 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
148 f.debug_struct("IntersperseWith")
149 .field("needs_sep", &self.needs_sep)
150 .field("iter", &self.iter)
151 .finish()
152 }
153}
154
155impl<I: AsyncIterator + Clone, G: Clone> std::clone::Clone for AsyncIntersperseWith<I, G>
156where
157 I::Item: Clone,
158{
159 fn clone(&self) -> Self {
160 Self {
161 separator: self.separator.clone(),
162 iter: self.iter.clone(),
163 needs_sep: self.needs_sep,
164 }
165 }
166
167 fn clone_from(&mut self, source: &Self) {
168 self.separator = source.separator.clone();
169 self.iter = source.iter.clone();
170 self.needs_sep = source.needs_sep;
171 }
172}
173
174impl<I, G, F> AsyncIntersperseWith<I, G>
175where
176 I: AsyncIterator,
177 G: FnMut() -> F,
178 F: Future<Output = I::Item>,
179{
180 pub fn new(iter: I, separator: G) -> Self {
181 Self {
182 iter: iter.peekable(),
183 separator,
184 needs_sep: false,
185 }
186 }
187}
188
189impl<I, G, F> AsyncIterator for AsyncIntersperseWith<I, G>
190where
191 I: AsyncIterator,
192 G: FnMut() -> F,
193 F: Future<Output = I::Item>,
194{
195 type Item = I::Item;
196
197 #[inline]
198 async fn next(&mut self) -> Option<I::Item> {
199 if self.needs_sep && self.iter.peek().await.is_some() {
200 self.needs_sep = false;
201 Some((self.separator)().await)
202 } else {
203 self.needs_sep = true;
204 self.iter.next().await
205 }
206 }
207
208 #[inline]
209 fn size_hint(&self) -> (usize, Option<usize>) {
210 intersperse_size_hint(&self.iter, self.needs_sep)
211 }
212}
213
214#[inline]
215fn intersperse_size_hint<I>(iter: &I, needs_sep: bool) -> (usize, Option<usize>)
216where
217 I: AsyncIterator,
218{
219 let (lo, hi) = iter.size_hint();
220 let next_is_elem = !needs_sep;
221 (
222 lo.saturating_sub(next_is_elem as usize).saturating_add(lo),
223 hi.and_then(|hi| hi.saturating_sub(next_is_elem as usize).checked_add(hi)),
224 )
225}