ntex_util/future/
mod.rs

1//! Utilities for futures
2use 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
22/// An owned dynamically typed Future for use in cases where
23/// you can't statically type your result or need to add some indirection.
24pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
25
26/// Creates a future that resolves to the next item in the stream.
27pub 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}