From 054f4fac740daaf5c2c6fcaccef9f374fc6c71ec Mon Sep 17 00:00:00 2001 From: k-nasa Date: Wed, 16 Oct 2019 16:53:33 +0900 Subject: [PATCH 1/8] feat: Add future::delay --- src/future/delay.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++ src/future/mod.rs | 2 ++ 2 files changed, 63 insertions(+) create mode 100644 src/future/delay.rs diff --git a/src/future/delay.rs b/src/future/delay.rs new file mode 100644 index 000000000..723c7c199 --- /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 cc3b7a5d5..d1a0f3150 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; } } From b251fc999a2faaeac6107af60f6dcf7ad077a5c3 Mon Sep 17 00:00:00 2001 From: k-nasa Date: Wed, 16 Oct 2019 19:18:05 +0900 Subject: [PATCH 2/8] Move delay method to FutureExt::delay --- src/future/future.rs | 22 ++++++++++++++++++++++ src/future/{ => future}/delay.rs | 22 ---------------------- src/future/mod.rs | 3 +-- 3 files changed, 23 insertions(+), 24 deletions(-) rename src/future/{ => future}/delay.rs (64%) diff --git a/src/future/future.rs b/src/future/future.rs index 556dc1acd..38f3d704c 100644 --- a/src/future/future.rs +++ b/src/future/future.rs @@ -105,6 +105,28 @@ extension_trait! { } pub trait FutureExt: std::future::Future { + /// 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; + /// use async_std::future::FutureExt; + /// + /// let a = future::ready(1).delay(Duration::from_millis(2000)); + /// dbg!(a.await); + /// # }) + /// ``` + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + #[cfg(any(feature = "unstable", feature = "docs"))] + fn delay(self, dur: Duration) -> DelayFuture + where + Self: Future + Sized + { + DelayFuture::new(self, dur) + } } impl Future for Box { diff --git a/src/future/delay.rs b/src/future/future/delay.rs similarity index 64% rename from src/future/delay.rs rename to src/future/future/delay.rs index 723c7c199..319b4ff8e 100644 --- a/src/future/delay.rs +++ b/src/future/future/delay.rs @@ -6,28 +6,6 @@ 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 { diff --git a/src/future/mod.rs b/src/future/mod.rs index d1a0f3150..6bfd6303c 100644 --- a/src/future/mod.rs +++ b/src/future/mod.rs @@ -51,6 +51,7 @@ pub use async_macros::{select, try_select}; use cfg_if::cfg_if; pub use future::Future; +pub use future::FutureExt; pub use pending::pending; pub use poll_fn::poll_fn; pub use ready::ready; @@ -65,9 +66,7 @@ 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; } } From 358d2bc038f8894794ad71b6003938452859093b Mon Sep 17 00:00:00 2001 From: k-nasa Date: Wed, 16 Oct 2019 19:20:07 +0900 Subject: [PATCH 3/8] Add import crate --- src/future/future.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/future/future.rs b/src/future/future.rs index 38f3d704c..5254ac047 100644 --- a/src/future/future.rs +++ b/src/future/future.rs @@ -9,6 +9,15 @@ cfg_if::cfg_if! { } } +cfg_if::cfg_if! { + if #[cfg(any(feature = "unstable", feature = "docs"))] { + mod delay; + + use std::time::Duration; + use delay::DelayFuture; + } +} + extension_trait! { #[doc = r#" A future represents an asynchronous computation. From 9d55fff81da0d4f76a9266df399fd8084406d4d2 Mon Sep 17 00:00:00 2001 From: k-nasa Date: Wed, 16 Oct 2019 22:38:28 +0900 Subject: [PATCH 4/8] fix export FutureExt --- src/future/future.rs | 2 +- src/future/mod.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/future/future.rs b/src/future/future.rs index 5254ac047..484977231 100644 --- a/src/future/future.rs +++ b/src/future/future.rs @@ -120,9 +120,9 @@ extension_trait! { /// /// ``` /// # async_std::task::block_on(async { + /// use async_std::prelude::*; /// use async_std::future; /// use std::time::Duration; - /// use async_std::future::FutureExt; /// /// let a = future::ready(1).delay(Duration::from_millis(2000)); /// dbg!(a.await); diff --git a/src/future/mod.rs b/src/future/mod.rs index 6bfd6303c..cc3b7a5d5 100644 --- a/src/future/mod.rs +++ b/src/future/mod.rs @@ -51,7 +51,6 @@ pub use async_macros::{select, try_select}; use cfg_if::cfg_if; pub use future::Future; -pub use future::FutureExt; pub use pending::pending; pub use poll_fn::poll_fn; pub use ready::ready; From 53fa132d136cb3a47f6aa3c5ba7249c3d6b401a6 Mon Sep 17 00:00:00 2001 From: k-nasa Date: Wed, 16 Oct 2019 22:45:18 +0900 Subject: [PATCH 5/8] fix type Declaration --- src/future/future.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/future/future.rs b/src/future/future.rs index 484977231..abf7c183f 100644 --- a/src/future/future.rs +++ b/src/future/future.rs @@ -130,7 +130,7 @@ extension_trait! { /// ``` #[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg(any(feature = "unstable", feature = "docs"))] - fn delay(self, dur: Duration) -> DelayFuture + fn delay(self, dur: Duration) -> impl Future [DelayFuture] where Self: Future + Sized { From d97b3dfdf3a159608023aea7a197b522514d817a Mon Sep 17 00:00:00 2001 From: k-nasa Date: Thu, 24 Oct 2019 08:29:05 +0900 Subject: [PATCH 6/8] fix: Remove Pin API related unsafe code --- src/future/future/delay.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/future/future/delay.rs b/src/future/future/delay.rs index 319b4ff8e..53a4d75aa 100644 --- a/src/future/future/delay.rs +++ b/src/future/future/delay.rs @@ -2,21 +2,23 @@ use std::pin::Pin; use std::time::Duration; use futures_timer::Delay; +use pin_project_lite::pin_project; use crate::future::Future; use crate::task::{Context, Poll}; +pin_project! { #[doc(hidden)] #[derive(Debug)] -pub struct DelayFuture { - future: F, - delay: Delay, + pub struct DelayFuture { + #[pin] + future: F, + #[pin] + 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); @@ -27,10 +29,12 @@ impl DelayFuture { 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) { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + + match this.delay.poll(cx) { Poll::Pending => Poll::Pending, - Poll::Ready(_) => match self.future().poll(cx) { + Poll::Ready(_) => match this.future.poll(cx) { Poll::Ready(v) => Poll::Ready(v), Poll::Pending => Poll::Pending, }, From 613895d6be615430beb322c766b940387bd2992c Mon Sep 17 00:00:00 2001 From: k-nasa Date: Mon, 28 Oct 2019 13:58:54 +0900 Subject: [PATCH 7/8] doc: fix documantation text --- src/future/future.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/future/future.rs b/src/future/future.rs index e8075f1bf..fe685176a 100644 --- a/src/future/future.rs +++ b/src/future/future.rs @@ -107,7 +107,7 @@ extension_trait! { } pub trait FutureExt: std::future::Future { - /// Creates a future that is delayed before it starts yielding items. + /// Returns a Future that delays execution for a specified time. /// /// # Examples /// From c7dc147f739d3be5917b254cf85fd0733bd4f014 Mon Sep 17 00:00:00 2001 From: k-nasa Date: Tue, 29 Oct 2019 09:27:35 +0900 Subject: [PATCH 8/8] fix indent --- src/future/future/delay.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/future/future/delay.rs b/src/future/future/delay.rs index 53a4d75aa..d672541ee 100644 --- a/src/future/future/delay.rs +++ b/src/future/future/delay.rs @@ -8,8 +8,8 @@ use crate::future::Future; use crate::task::{Context, Poll}; pin_project! { -#[doc(hidden)] -#[derive(Debug)] + #[doc(hidden)] + #[derive(Debug)] pub struct DelayFuture { #[pin] future: F,