select_next_any/
lib.rs

1//! Stream combinator that can be used in the futures::select! macro. It is
2//! similar to futures::StreamExt::select_next_some, but instead of only
3//! resolving the Some variants, this one will return Option<T>. This is
4//! useful when you want to do some action after one stream completes.
5//! The bulk of this code was copied from futures::stream::SelectNextSome
6//! (Copyright (c) 2016 Alex Crichton, Copyright (c) 2017 The Tokio Authors).
7
8use 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/// Future for the [`select_next_any`](super::StreamExt::select_next_any)
29/// method.
30#[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}