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