1use core::pin::Pin;
9use futures::future::{FusedFuture, Future};
10use futures::stream::{FusedStream, StreamExt};
11use futures::task::{Context, Poll};
12
13pub trait SelectNextAnyExt {
14 fn select_next_any(&mut self) -> SelectNextAny<'_, Self>
15 where
16 Self: Unpin + FusedStream;
17}
18
19impl<T> SelectNextAnyExt for T
20where
21 T: Unpin + FusedStream,
22{
23 fn select_next_any(&mut self) -> SelectNextAny<'_, Self> {
24 SelectNextAny::new(self)
25 }
26}
27
28#[derive(Debug)]
31#[must_use = "futures do nothing unless you `.await` or poll them"]
32pub struct SelectNextAny<'a, St: ?Sized> {
33 stream: &'a mut St,
34}
35
36impl<'a, St: ?Sized> SelectNextAny<'a, St> {
37 fn new(stream: &'a mut St) -> Self {
38 SelectNextAny { stream }
39 }
40}
41
42impl<St: ?Sized + FusedStream + Unpin> FusedFuture for SelectNextAny<'_, St> {
43 fn is_terminated(&self) -> bool {
44 self.stream.is_terminated()
45 }
46}
47
48impl<St: ?Sized + FusedStream + Unpin> Future for SelectNextAny<'_, St> {
49 type Output = Option<St::Item>;
50
51 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
52 assert!(
53 !self.stream.is_terminated(),
54 "SelectNextAny polled after terminated"
55 );
56
57 self.stream.poll_next_unpin(cx)
58 }
59}