diff --git a/src/future/delay.rs b/src/future/delay.rs new file mode 100644 index 0000000..723c7c1 --- /dev/null +++ b/src/future/delay.rs @@ -0,0 +1,61 @@ +use std::pin::Pin; +use std::time::Duration; + +use futures_timer::Delay; + +use crate::future::Future; +use crate::task::{Context, Poll}; + +/// Creates a future that is delayed before it starts yielding items. +/// +/// # Examples +/// +/// ``` +/// # async_std::task::block_on(async { +/// use async_std::future; +/// use std::time::Duration; + +/// let a = future::delay(future::ready(1) ,Duration::from_millis(2000)); +/// dbg!(a.await); +/// # }) +/// ``` +#[cfg_attr(feature = "docs", doc(cfg(unstable)))] +#[cfg(any(feature = "unstable", feature = "docs"))] +pub fn delay(f: F, dur: Duration) -> DelayFuture +where + F: Future, +{ + DelayFuture::new(f, dur) +} + +#[doc(hidden)] +#[derive(Debug)] +pub struct DelayFuture { + future: F, + delay: Delay, +} + +impl DelayFuture { + pin_utils::unsafe_pinned!(future: F); + pin_utils::unsafe_pinned!(delay: Delay); + + pub fn new(future: F, dur: Duration) -> DelayFuture { + let delay = Delay::new(dur); + + DelayFuture { future, delay } + } +} + +impl Future for DelayFuture { + type Output = F::Output; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.as_mut().delay().poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(_) => match self.future().poll(cx) { + Poll::Ready(v) => Poll::Ready(v), + Poll::Pending => Poll::Pending, + }, + } + } +} diff --git a/src/future/mod.rs b/src/future/mod.rs index cc3b7a5..d1a0f31 100644 --- a/src/future/mod.rs +++ b/src/future/mod.rs @@ -65,7 +65,9 @@ mod timeout; cfg_if! { if #[cfg(any(feature = "unstable", feature = "docs"))] { mod into_future; + mod delay; pub use into_future::IntoFuture; + pub use delay::delay; } }