futures_util/stream/
select_all.rs1use core::fmt::{self, Debug};
4use core::iter::FromIterator;
5use core::pin::Pin;
6
7use futures_core::ready;
8use futures_core::stream::{FusedStream, Stream};
9use futures_core::task::{Context, Poll};
10
11use pin_project_lite::pin_project;
12
13use super::assert_stream;
14use crate::stream::{futures_unordered, FuturesUnordered, StreamExt, StreamFuture};
15
16pin_project! {
17 #[must_use = "streams do nothing unless polled"]
30 pub struct SelectAll<St> {
31 #[pin]
32 inner: FuturesUnordered<StreamFuture<St>>,
33 }
34}
35
36impl<St: Debug> Debug for SelectAll<St> {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "SelectAll {{ ... }}")
39 }
40}
41
42impl<St: Stream + Unpin> SelectAll<St> {
43 pub fn new() -> Self {
48 Self { inner: FuturesUnordered::new() }
49 }
50
51 pub fn len(&self) -> usize {
55 self.inner.len()
56 }
57
58 pub fn is_empty(&self) -> bool {
60 self.inner.is_empty()
61 }
62
63 pub fn push(&mut self, stream: St) {
70 self.inner.push(stream.into_future());
71 }
72
73 pub fn iter(&self) -> Iter<'_, St> {
75 Iter(self.inner.iter())
76 }
77
78 pub fn iter_mut(&mut self) -> IterMut<'_, St> {
80 IterMut(self.inner.iter_mut())
81 }
82
83 pub fn clear(&mut self) {
85 self.inner.clear()
86 }
87}
88
89impl<St: Stream + Unpin> Default for SelectAll<St> {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95impl<St: Stream + Unpin> Stream for SelectAll<St> {
96 type Item = St::Item;
97
98 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
99 loop {
100 match ready!(self.inner.poll_next_unpin(cx)) {
101 Some((Some(item), remaining)) => {
102 self.push(remaining);
103 return Poll::Ready(Some(item));
104 }
105 Some((None, _)) => {
106 }
111 None => return Poll::Ready(None),
112 }
113 }
114 }
115}
116
117impl<St: Stream + Unpin> FusedStream for SelectAll<St> {
118 fn is_terminated(&self) -> bool {
119 self.inner.is_terminated()
120 }
121}
122
123pub fn select_all<I>(streams: I) -> SelectAll<I::Item>
136where
137 I: IntoIterator,
138 I::Item: Stream + Unpin,
139{
140 let mut set = SelectAll::new();
141
142 for stream in streams {
143 set.push(stream);
144 }
145
146 assert_stream::<<I::Item as Stream>::Item, _>(set)
147}
148
149impl<St: Stream + Unpin> FromIterator<St> for SelectAll<St> {
150 fn from_iter<T: IntoIterator<Item = St>>(iter: T) -> Self {
151 select_all(iter)
152 }
153}
154
155impl<St: Stream + Unpin> Extend<St> for SelectAll<St> {
156 fn extend<T: IntoIterator<Item = St>>(&mut self, iter: T) {
157 for st in iter {
158 self.push(st)
159 }
160 }
161}
162
163impl<St: Stream + Unpin> IntoIterator for SelectAll<St> {
164 type Item = St;
165 type IntoIter = IntoIter<St>;
166
167 fn into_iter(self) -> Self::IntoIter {
168 IntoIter(self.inner.into_iter())
169 }
170}
171
172impl<'a, St: Stream + Unpin> IntoIterator for &'a SelectAll<St> {
173 type Item = &'a St;
174 type IntoIter = Iter<'a, St>;
175
176 fn into_iter(self) -> Self::IntoIter {
177 self.iter()
178 }
179}
180
181impl<'a, St: Stream + Unpin> IntoIterator for &'a mut SelectAll<St> {
182 type Item = &'a mut St;
183 type IntoIter = IterMut<'a, St>;
184
185 fn into_iter(self) -> Self::IntoIter {
186 self.iter_mut()
187 }
188}
189
190#[derive(Debug)]
192pub struct Iter<'a, St: Unpin>(futures_unordered::Iter<'a, StreamFuture<St>>);
193
194#[derive(Debug)]
196pub struct IterMut<'a, St: Unpin>(futures_unordered::IterMut<'a, StreamFuture<St>>);
197
198#[derive(Debug)]
200pub struct IntoIter<St: Unpin>(futures_unordered::IntoIter<StreamFuture<St>>);
201
202impl<'a, St: Stream + Unpin> Iterator for Iter<'a, St> {
203 type Item = &'a St;
204
205 fn next(&mut self) -> Option<Self::Item> {
206 let st = self.0.next()?;
207 let next = st.get_ref();
208 debug_assert!(next.is_some());
210 next
211 }
212
213 fn size_hint(&self) -> (usize, Option<usize>) {
214 self.0.size_hint()
215 }
216}
217
218impl<St: Stream + Unpin> ExactSizeIterator for Iter<'_, St> {}
219
220impl<'a, St: Stream + Unpin> Iterator for IterMut<'a, St> {
221 type Item = &'a mut St;
222
223 fn next(&mut self) -> Option<Self::Item> {
224 let st = self.0.next()?;
225 let next = st.get_mut();
226 debug_assert!(next.is_some());
228 next
229 }
230
231 fn size_hint(&self) -> (usize, Option<usize>) {
232 self.0.size_hint()
233 }
234}
235
236impl<St: Stream + Unpin> ExactSizeIterator for IterMut<'_, St> {}
237
238impl<St: Stream + Unpin> Iterator for IntoIter<St> {
239 type Item = St;
240
241 fn next(&mut self) -> Option<Self::Item> {
242 let st = self.0.next()?;
243 let next = st.into_inner();
244 debug_assert!(next.is_some());
246 next
247 }
248
249 fn size_hint(&self) -> (usize, Option<usize>) {
250 self.0.size_hint()
251 }
252}
253
254impl<St: Stream + Unpin> ExactSizeIterator for IntoIter<St> {}