futures_util/future/
select_ok.rs1use super::assert_future;
2use crate::future::TryFutureExt;
3use alloc::vec::Vec;
4use core::iter::FromIterator;
5use core::mem;
6use core::pin::Pin;
7use futures_core::future::{Future, TryFuture};
8use futures_core::task::{Context, Poll};
9
10#[derive(Debug)]
12#[must_use = "futures do nothing unless you `.await` or poll them"]
13pub struct SelectOk<Fut> {
14 inner: Vec<Fut>,
15}
16
17impl<Fut: Unpin> Unpin for SelectOk<Fut> {}
18
19pub fn select_ok<I>(iter: I) -> SelectOk<I::Item>
33where
34 I: IntoIterator,
35 I::Item: TryFuture + Unpin,
36{
37 let ret = SelectOk { inner: iter.into_iter().collect() };
38 assert!(!ret.inner.is_empty(), "iterator provided to select_ok was empty");
39 assert_future::<
40 Result<(<I::Item as TryFuture>::Ok, Vec<I::Item>), <I::Item as TryFuture>::Error>,
41 _,
42 >(ret)
43}
44
45impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
46 type Output = Result<(Fut::Ok, Vec<Fut>), Fut::Error>;
47
48 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
49 loop {
51 let item =
52 self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.try_poll_unpin(cx) {
53 Poll::Pending => None,
54 Poll::Ready(e) => Some((i, e)),
55 });
56 match item {
57 Some((idx, res)) => {
58 drop(self.inner.remove(idx));
60 match res {
61 Ok(e) => {
62 let rest = mem::take(&mut self.inner);
63 return Poll::Ready(Ok((e, rest)));
64 }
65 Err(e) => {
66 if self.inner.is_empty() {
67 return Poll::Ready(Err(e));
68 }
69 }
70 }
71 }
72 None => {
73 return Poll::Pending;
75 }
76 }
77 }
78 }
79}
80
81impl<Fut: TryFuture + Unpin> FromIterator<Fut> for SelectOk<Fut> {
82 fn from_iter<T: IntoIterator<Item = Fut>>(iter: T) -> Self {
83 select_ok(iter)
84 }
85}