1use std::future::{Future, poll_fn};
3use std::task::{Context, Poll, ready};
4use std::{mem, pin::Pin};
5
6pub use futures_core::{Stream, TryFuture};
7
8mod either;
9mod join;
10mod lazy;
11mod on_drop;
12mod ready;
13mod select;
14
15pub use self::either::Either;
16pub use self::join::{join, join_all};
17pub use self::lazy::{Lazy, lazy};
18pub use self::on_drop::{OnDropFn, OnDropFuture, OnDropFutureExt};
19pub use self::ready::Ready;
20pub use self::select::select;
21
22pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
25
26pub async fn stream_recv<S>(stream: &mut S) -> Option<S::Item>
28where
29 S: Stream + Unpin,
30{
31 poll_fn(|cx| Pin::new(&mut *stream).poll_next(cx)).await
32}
33
34enum MaybeDone<F>
35where
36 F: Future,
37{
38 Pending(F),
39 Done(F::Output),
40 Gone,
41}
42
43impl<F: Future> MaybeDone<F> {
44 fn take_output(self: Pin<&mut Self>) -> Option<F::Output> {
45 match &*self {
46 Self::Done(_) => {}
47 Self::Pending(_) | Self::Gone => return None,
48 }
49 unsafe {
50 match mem::replace(self.get_unchecked_mut(), Self::Gone) {
51 MaybeDone::Done(output) => Some(output),
52 _ => unreachable!(),
53 }
54 }
55 }
56}
57
58impl<F: Future> Future for MaybeDone<F> {
59 type Output = ();
60
61 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
62 unsafe {
63 match self.as_mut().get_unchecked_mut() {
64 MaybeDone::Pending(f) => {
65 let res = ready!(Pin::new_unchecked(f).poll(cx));
66 self.set(Self::Done(res));
67 }
68 MaybeDone::Done(_) => {}
69 MaybeDone::Gone => panic!("MaybeDone polled after value taken"),
70 }
71 }
72 Poll::Ready(())
73 }
74}