summaryrefslogtreecommitdiffstats
path: root/futures/src
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector0193@gmail.com>2022-01-31 17:01:19 +0700
committerLibravatar GitHub <noreply@github.com>2022-01-31 17:01:19 +0700
commite4ef29ef20724c3d1a4beff39ddfdaf6d45f9683 (patch)
tree6e0c9c38366c9d70204c80fc66bd8e8a7652cf52 /futures/src
parentc75ed37148b019358b0297171cf31b2577eeb9ae (diff)
parent6f604ab3995cb345aacf183a569589988aa3ad1f (diff)
downloadiced-e4ef29ef20724c3d1a4beff39ddfdaf6d45f9683.tar.gz
iced-e4ef29ef20724c3d1a4beff39ddfdaf6d45f9683.tar.bz2
iced-e4ef29ef20724c3d1a4beff39ddfdaf6d45f9683.zip
Merge pull request #1096 from pacmancoder/feat/wgpu-webgl
Experimental WebGL wgpu backend support
Diffstat (limited to 'futures/src')
-rw-r--r--futures/src/backend.rs10
-rw-r--r--futures/src/backend/default.rs38
-rw-r--r--futures/src/backend/native.rs16
-rw-r--r--futures/src/backend/native/async_std.rs59
-rw-r--r--futures/src/backend/native/smol.rs59
-rw-r--r--futures/src/backend/native/thread_pool.rs (renamed from futures/src/executor/thread_pool.rs)7
-rw-r--r--futures/src/backend/native/tokio.rs72
-rw-r--r--futures/src/backend/null.rs (renamed from futures/src/executor/null.rs)7
-rw-r--r--futures/src/backend/wasm.rs2
-rw-r--r--futures/src/backend/wasm/wasm_bindgen.rs59
-rw-r--r--futures/src/executor.rs42
-rw-r--r--futures/src/executor/async_std.rs18
-rw-r--r--futures/src/executor/smol.rs18
-rw-r--r--futures/src/executor/tokio.rs22
-rw-r--r--futures/src/executor/wasm_bindgen.rs15
-rw-r--r--futures/src/lib.rs17
-rw-r--r--futures/src/maybe_send.rs21
-rw-r--r--futures/src/runtime.rs13
-rw-r--r--futures/src/subscription/tracker.rs6
-rw-r--r--futures/src/time.rs105
20 files changed, 358 insertions, 248 deletions
diff --git a/futures/src/backend.rs b/futures/src/backend.rs
new file mode 100644
index 00000000..1cc4af80
--- /dev/null
+++ b/futures/src/backend.rs
@@ -0,0 +1,10 @@
+//! The underlying implementations of the `iced_futures` contract!
+pub mod null;
+
+#[cfg(not(target_arch = "wasm32"))]
+pub mod native;
+
+#[cfg(target_arch = "wasm32")]
+pub mod wasm;
+
+pub mod default;
diff --git a/futures/src/backend/default.rs b/futures/src/backend/default.rs
new file mode 100644
index 00000000..76264f55
--- /dev/null
+++ b/futures/src/backend/default.rs
@@ -0,0 +1,38 @@
+//! A default, cross-platform backend.
+//!
+//! - On native platforms, it will use:
+//! - `backend::native::tokio` when the `tokio` feature is enabled.
+//! - `backend::native::async-std` when the `async-std` feature is
+//! enabled.
+//! - `backend::native::smol` when the `smol` feature is enabled.
+//! - `backend::native::thread_pool` otherwise.
+//!
+//! - On Wasm, it will use `backend::wasm::wasm_bindgen`.
+#[cfg(not(target_arch = "wasm32"))]
+mod platform {
+ #[cfg(feature = "tokio")]
+ pub use crate::backend::native::tokio::*;
+
+ #[cfg(all(feature = "async-std", not(feature = "tokio"),))]
+ pub use crate::backend::native::async_std::*;
+
+ #[cfg(all(
+ feature = "smol",
+ not(any(feature = "tokio", feature = "async-std")),
+ ))]
+ pub use crate::backend::native::smol::*;
+
+ #[cfg(not(any(
+ feature = "tokio",
+ feature = "async-std",
+ feature = "smol",
+ )))]
+ pub use crate::backend::native::thread_pool::*;
+}
+
+#[cfg(target_arch = "wasm32")]
+mod platform {
+ pub use crate::backend::wasm::wasm_bindgen::*;
+}
+
+pub use platform::*;
diff --git a/futures/src/backend/native.rs b/futures/src/backend/native.rs
new file mode 100644
index 00000000..4199ad16
--- /dev/null
+++ b/futures/src/backend/native.rs
@@ -0,0 +1,16 @@
+//! Backends that are only available in native platforms: Windows, macOS, or Linux.
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio",)))]
+#[cfg(feature = "tokio")]
+pub mod tokio;
+
+#[cfg_attr(docsrs, doc(cfg(feature = "async-std",)))]
+#[cfg(feature = "async-std")]
+pub mod async_std;
+
+#[cfg_attr(docsrs, doc(cfg(feature = "smol",)))]
+#[cfg(feature = "smol")]
+pub mod smol;
+
+#[cfg_attr(docsrs, doc(cfg(feature = "thread-pool",)))]
+#[cfg(feature = "thread-pool")]
+pub mod thread_pool;
diff --git a/futures/src/backend/native/async_std.rs b/futures/src/backend/native/async_std.rs
new file mode 100644
index 00000000..e8641626
--- /dev/null
+++ b/futures/src/backend/native/async_std.rs
@@ -0,0 +1,59 @@
+//! An `async-std` backend.
+use futures::Future;
+
+/// An `async-std` executor.
+#[derive(Debug)]
+pub struct Executor;
+
+impl crate::Executor for Executor {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Self)
+ }
+
+ fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
+ let _ = async_std::task::spawn(future);
+ }
+}
+
+pub mod time {
+ //! Listen and react to time.
+ use crate::subscription::{self, Subscription};
+
+ /// Returns a [`Subscription`] that produces messages at a set interval.
+ ///
+ /// The first message is produced after a `duration`, and then continues to
+ /// produce more messages every `duration` after that.
+ pub fn every<H: std::hash::Hasher, E>(
+ duration: std::time::Duration,
+ ) -> Subscription<H, E, std::time::Instant> {
+ Subscription::from_recipe(Every(duration))
+ }
+
+ #[derive(Debug)]
+ struct Every(std::time::Duration);
+
+ impl<H, E> subscription::Recipe<H, E> for Every
+ where
+ H: std::hash::Hasher,
+ {
+ type Output = std::time::Instant;
+
+ fn hash(&self, state: &mut H) {
+ use std::hash::Hash;
+
+ std::any::TypeId::of::<Self>().hash(state);
+ self.0.hash(state);
+ }
+
+ fn stream(
+ self: Box<Self>,
+ _input: futures::stream::BoxStream<'static, E>,
+ ) -> futures::stream::BoxStream<'static, Self::Output> {
+ use futures::stream::StreamExt;
+
+ async_std::stream::interval(self.0)
+ .map(|_| std::time::Instant::now())
+ .boxed()
+ }
+ }
+}
diff --git a/futures/src/backend/native/smol.rs b/futures/src/backend/native/smol.rs
new file mode 100644
index 00000000..d5201cde
--- /dev/null
+++ b/futures/src/backend/native/smol.rs
@@ -0,0 +1,59 @@
+//! A `smol` backend.
+
+use futures::Future;
+
+/// A `smol` executor.
+#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
+#[derive(Debug)]
+pub struct Executor;
+
+impl crate::Executor for Executor {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Self)
+ }
+
+ fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
+ smol::spawn(future).detach();
+ }
+}
+
+pub mod time {
+ //! Listen and react to time.
+ use crate::subscription::{self, Subscription};
+
+ /// Returns a [`Subscription`] that produces messages at a set interval.
+ ///
+ /// The first message is produced after a `duration`, and then continues to
+ /// produce more messages every `duration` after that.
+ pub fn every<H: std::hash::Hasher, E>(
+ duration: std::time::Duration,
+ ) -> Subscription<H, E, std::time::Instant> {
+ Subscription::from_recipe(Every(duration))
+ }
+
+ #[derive(Debug)]
+ struct Every(std::time::Duration);
+
+ impl<H, E> subscription::Recipe<H, E> for Every
+ where
+ H: std::hash::Hasher,
+ {
+ type Output = std::time::Instant;
+
+ fn hash(&self, state: &mut H) {
+ use std::hash::Hash;
+
+ std::any::TypeId::of::<Self>().hash(state);
+ self.0.hash(state);
+ }
+
+ fn stream(
+ self: Box<Self>,
+ _input: futures::stream::BoxStream<'static, E>,
+ ) -> futures::stream::BoxStream<'static, Self::Output> {
+ use futures::stream::StreamExt;
+
+ smol::Timer::interval(self.0).boxed()
+ }
+ }
+}
diff --git a/futures/src/executor/thread_pool.rs b/futures/src/backend/native/thread_pool.rs
index a6c6168e..6e791533 100644
--- a/futures/src/executor/thread_pool.rs
+++ b/futures/src/backend/native/thread_pool.rs
@@ -1,12 +1,11 @@
-use crate::Executor;
-
+//! A `ThreadPool` backend.
use futures::Future;
-/// A thread pool runtime for futures.
+/// A thread pool executor for futures.
#[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))]
pub type ThreadPool = futures::executor::ThreadPool;
-impl Executor for futures::executor::ThreadPool {
+impl crate::Executor for futures::executor::ThreadPool {
fn new() -> Result<Self, futures::io::Error> {
futures::executor::ThreadPool::new()
}
diff --git a/futures/src/backend/native/tokio.rs b/futures/src/backend/native/tokio.rs
new file mode 100644
index 00000000..f86b0ea3
--- /dev/null
+++ b/futures/src/backend/native/tokio.rs
@@ -0,0 +1,72 @@
+//! A `tokio` backend.
+use futures::Future;
+
+/// A `tokio` executor.
+pub type Executor = tokio::runtime::Runtime;
+
+impl crate::Executor for Executor {
+ fn new() -> Result<Self, futures::io::Error> {
+ tokio::runtime::Runtime::new()
+ }
+
+ fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
+ let _ = tokio::runtime::Runtime::spawn(self, future);
+ }
+
+ fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
+ let _guard = tokio::runtime::Runtime::enter(self);
+ f()
+ }
+}
+
+pub mod time {
+ //! Listen and react to time.
+ use crate::subscription::{self, Subscription};
+
+ /// Returns a [`Subscription`] that produces messages at a set interval.
+ ///
+ /// The first message is produced after a `duration`, and then continues to
+ /// produce more messages every `duration` after that.
+ pub fn every<H: std::hash::Hasher, E>(
+ duration: std::time::Duration,
+ ) -> Subscription<H, E, std::time::Instant> {
+ Subscription::from_recipe(Every(duration))
+ }
+
+ #[derive(Debug)]
+ struct Every(std::time::Duration);
+
+ impl<H, E> subscription::Recipe<H, E> for Every
+ where
+ H: std::hash::Hasher,
+ {
+ type Output = std::time::Instant;
+
+ fn hash(&self, state: &mut H) {
+ use std::hash::Hash;
+
+ std::any::TypeId::of::<Self>().hash(state);
+ self.0.hash(state);
+ }
+
+ fn stream(
+ self: Box<Self>,
+ _input: futures::stream::BoxStream<'static, E>,
+ ) -> futures::stream::BoxStream<'static, Self::Output> {
+ use futures::stream::StreamExt;
+
+ let start = tokio::time::Instant::now() + self.0;
+
+ let stream = {
+ futures::stream::unfold(
+ tokio::time::interval_at(start, self.0),
+ |mut interval| async move {
+ Some((interval.tick().await, interval))
+ },
+ )
+ };
+
+ stream.map(tokio::time::Instant::into_std).boxed()
+ }
+ }
+}
diff --git a/futures/src/executor/null.rs b/futures/src/backend/null.rs
index 65e2e2df..e22e7921 100644
--- a/futures/src/executor/null.rs
+++ b/futures/src/backend/null.rs
@@ -1,12 +1,11 @@
-use crate::Executor;
-
+//! A backend that does nothing!
use futures::Future;
/// An executor that drops all the futures, instead of spawning them.
#[derive(Debug)]
-pub struct Null;
+pub struct Executor;
-impl Executor for Null {
+impl crate::Executor for Executor {
fn new() -> Result<Self, futures::io::Error> {
Ok(Self)
}
diff --git a/futures/src/backend/wasm.rs b/futures/src/backend/wasm.rs
new file mode 100644
index 00000000..a49d9e55
--- /dev/null
+++ b/futures/src/backend/wasm.rs
@@ -0,0 +1,2 @@
+//! Backends that are only available on Wasm targets.
+pub mod wasm_bindgen;
diff --git a/futures/src/backend/wasm/wasm_bindgen.rs b/futures/src/backend/wasm/wasm_bindgen.rs
new file mode 100644
index 00000000..b726501a
--- /dev/null
+++ b/futures/src/backend/wasm/wasm_bindgen.rs
@@ -0,0 +1,59 @@
+//! A `wasm-bindgein-futures` backend.
+
+/// A `wasm-bindgen-futures` executor.
+#[derive(Debug)]
+pub struct Executor;
+
+impl crate::Executor for Executor {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Self)
+ }
+
+ fn spawn(&self, future: impl futures::Future<Output = ()> + 'static) {
+ wasm_bindgen_futures::spawn_local(future);
+ }
+}
+
+pub mod time {
+ //! Listen and react to time.
+ use crate::subscription::{self, Subscription};
+ use crate::BoxStream;
+
+ /// Returns a [`Subscription`] that produces messages at a set interval.
+ ///
+ /// The first message is produced after a `duration`, and then continues to
+ /// produce more messages every `duration` after that.
+ pub fn every<H: std::hash::Hasher, E>(
+ duration: std::time::Duration,
+ ) -> Subscription<H, E, wasm_timer::Instant> {
+ Subscription::from_recipe(Every(duration))
+ }
+
+ #[derive(Debug)]
+ struct Every(std::time::Duration);
+
+ impl<H, E> subscription::Recipe<H, E> for Every
+ where
+ H: std::hash::Hasher,
+ {
+ type Output = wasm_timer::Instant;
+
+ fn hash(&self, state: &mut H) {
+ use std::hash::Hash;
+
+ std::any::TypeId::of::<Self>().hash(state);
+ self.0.hash(state);
+ }
+
+ fn stream(
+ self: Box<Self>,
+ _input: BoxStream<E>,
+ ) -> BoxStream<Self::Output> {
+ use futures::stream::StreamExt;
+
+ wasm_timer::Interval::new(self.0)
+ .map(|_| wasm_timer::Instant::now())
+ .boxed_local()
+ }
+ }
+}
diff --git a/futures/src/executor.rs b/futures/src/executor.rs
index 23682f32..5ac76081 100644
--- a/futures/src/executor.rs
+++ b/futures/src/executor.rs
@@ -1,38 +1,5 @@
//! Choose your preferred executor to power a runtime.
-mod null;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "thread-pool"))]
-mod thread_pool;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))]
-mod tokio;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))]
-mod async_std;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "smol"))]
-mod smol;
-
-#[cfg(target_arch = "wasm32")]
-mod wasm_bindgen;
-
-pub use null::Null;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "thread-pool"))]
-pub use thread_pool::ThreadPool;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))]
-pub use self::tokio::Tokio;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))]
-pub use self::async_std::AsyncStd;
-
-#[cfg(all(not(target_arch = "wasm32"), feature = "smol"))]
-pub use self::smol::Smol;
-
-#[cfg(target_arch = "wasm32")]
-pub use wasm_bindgen::WasmBindgen;
-
+use crate::MaybeSend;
use futures::Future;
/// A type that can run futures.
@@ -43,12 +10,7 @@ pub trait Executor: Sized {
Self: Sized;
/// Spawns a future in the [`Executor`].
- #[cfg(not(target_arch = "wasm32"))]
- fn spawn(&self, future: impl Future<Output = ()> + Send + 'static);
-
- /// Spawns a local future in the [`Executor`].
- #[cfg(target_arch = "wasm32")]
- fn spawn(&self, future: impl Future<Output = ()> + 'static);
+ fn spawn(&self, future: impl Future<Output = ()> + MaybeSend + 'static);
/// Runs the given closure inside the [`Executor`].
///
diff --git a/futures/src/executor/async_std.rs b/futures/src/executor/async_std.rs
deleted file mode 100644
index 471be369..00000000
--- a/futures/src/executor/async_std.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use crate::Executor;
-
-use futures::Future;
-
-/// An `async-std` runtime.
-#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
-#[derive(Debug)]
-pub struct AsyncStd;
-
-impl Executor for AsyncStd {
- fn new() -> Result<Self, futures::io::Error> {
- Ok(Self)
- }
-
- fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
- let _ = async_std::task::spawn(future);
- }
-}
diff --git a/futures/src/executor/smol.rs b/futures/src/executor/smol.rs
deleted file mode 100644
index deafd43a..00000000
--- a/futures/src/executor/smol.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use crate::Executor;
-
-use futures::Future;
-
-/// A `smol` runtime.
-#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
-#[derive(Debug)]
-pub struct Smol;
-
-impl Executor for Smol {
- fn new() -> Result<Self, futures::io::Error> {
- Ok(Self)
- }
-
- fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
- smol::spawn(future).detach();
- }
-}
diff --git a/futures/src/executor/tokio.rs b/futures/src/executor/tokio.rs
deleted file mode 100644
index c6a21cec..00000000
--- a/futures/src/executor/tokio.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use crate::Executor;
-
-use futures::Future;
-
-/// A `tokio` runtime.
-#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
-pub type Tokio = tokio::runtime::Runtime;
-
-impl Executor for Tokio {
- fn new() -> Result<Self, futures::io::Error> {
- tokio::runtime::Runtime::new()
- }
-
- fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
- let _ = tokio::runtime::Runtime::spawn(self, future);
- }
-
- fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
- let _guard = tokio::runtime::Runtime::enter(self);
- f()
- }
-}
diff --git a/futures/src/executor/wasm_bindgen.rs b/futures/src/executor/wasm_bindgen.rs
deleted file mode 100644
index 94d694c8..00000000
--- a/futures/src/executor/wasm_bindgen.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use crate::Executor;
-
-/// A `wasm-bindgen-futures` runtime.
-#[derive(Debug)]
-pub struct WasmBindgen;
-
-impl Executor for WasmBindgen {
- fn new() -> Result<Self, futures::io::Error> {
- Ok(Self)
- }
-
- fn spawn(&self, future: impl futures::Future<Output = ()> + 'static) {
- wasm_bindgen_futures::spawn_local(future);
- }
-}
diff --git a/futures/src/lib.rs b/futures/src/lib.rs
index dbcb8aca..b0b2f6ce 100644
--- a/futures/src/lib.rs
+++ b/futures/src/lib.rs
@@ -14,27 +14,16 @@
pub use futures;
mod command;
+mod maybe_send;
mod runtime;
+pub mod backend;
pub mod executor;
pub mod subscription;
-#[cfg(all(
- any(feature = "tokio", feature = "async-std", feature = "smol"),
- not(target_arch = "wasm32")
-))]
-#[cfg_attr(
- docsrs,
- doc(cfg(any(
- feature = "tokio",
- feature = "async-std",
- feature = "smol"
- )))
-)]
-pub mod time;
-
pub use command::Command;
pub use executor::Executor;
+pub use maybe_send::MaybeSend;
pub use platform::*;
pub use runtime::Runtime;
pub use subscription::Subscription;
diff --git a/futures/src/maybe_send.rs b/futures/src/maybe_send.rs
new file mode 100644
index 00000000..a6670f0e
--- /dev/null
+++ b/futures/src/maybe_send.rs
@@ -0,0 +1,21 @@
+#[cfg(not(target_arch = "wasm32"))]
+mod platform {
+ /// An extension trait that enforces `Send` only on native platforms.
+ ///
+ /// Useful to write cross-platform async code!
+ pub trait MaybeSend: Send {}
+
+ impl<T> MaybeSend for T where T: Send {}
+}
+
+#[cfg(target_arch = "wasm32")]
+mod platform {
+ /// An extension trait that enforces `Send` only on native platforms.
+ ///
+ /// Useful to write cross-platform async code!
+ pub trait MaybeSend {}
+
+ impl<T> MaybeSend for T {}
+}
+
+pub use platform::MaybeSend;
diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs
index 7779e235..2034ed6c 100644
--- a/futures/src/runtime.rs
+++ b/futures/src/runtime.rs
@@ -1,6 +1,6 @@
//! Run commands and keep track of subscriptions.
-use crate::BoxFuture;
-use crate::{subscription, Executor, Subscription};
+use crate::subscription;
+use crate::{BoxFuture, Executor, MaybeSend, Subscription};
use futures::{channel::mpsc, Sink};
use std::marker::PhantomData;
@@ -23,9 +23,12 @@ where
Hasher: std::hash::Hasher + Default,
Event: Send + Clone + 'static,
Executor: self::Executor,
- Sender:
- Sink<Message, Error = mpsc::SendError> + Unpin + Send + Clone + 'static,
- Message: Send + 'static,
+ Sender: Sink<Message, Error = mpsc::SendError>
+ + Unpin
+ + MaybeSend
+ + Clone
+ + 'static,
+ Message: MaybeSend + 'static,
{
/// Creates a new empty [`Runtime`].
///
diff --git a/futures/src/subscription/tracker.rs b/futures/src/subscription/tracker.rs
index 3a8d4a87..421fb917 100644
--- a/futures/src/subscription/tracker.rs
+++ b/futures/src/subscription/tracker.rs
@@ -1,4 +1,4 @@
-use crate::{BoxFuture, Subscription};
+use crate::{BoxFuture, MaybeSend, Subscription};
use futures::{channel::mpsc, sink::Sink};
use std::{collections::HashMap, marker::PhantomData};
@@ -57,11 +57,11 @@ where
receiver: Receiver,
) -> Vec<BoxFuture<()>>
where
- Message: 'static + Send,
+ Message: 'static + MaybeSend,
Receiver: 'static
+ Sink<Message, Error = mpsc::SendError>
+ Unpin
- + Send
+ + MaybeSend
+ Clone,
{
use futures::{future::FutureExt, stream::StreamExt};
diff --git a/futures/src/time.rs b/futures/src/time.rs
deleted file mode 100644
index 0ece6f04..00000000
--- a/futures/src/time.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-//! Listen and react to time.
-use crate::subscription::{self, Subscription};
-
-/// Returns a [`Subscription`] that produces messages at a set interval.
-///
-/// The first message is produced after a `duration`, and then continues to
-/// produce more messages every `duration` after that.
-pub fn every<H: std::hash::Hasher, E>(
- duration: std::time::Duration,
-) -> Subscription<H, E, std::time::Instant> {
- Subscription::from_recipe(Every(duration))
-}
-
-struct Every(std::time::Duration);
-
-#[cfg(all(
- not(any(feature = "tokio", feature = "async-std")),
- feature = "smol"
-))]
-impl<H, E> subscription::Recipe<H, E> for Every
-where
- H: std::hash::Hasher,
-{
- type Output = std::time::Instant;
-
- fn hash(&self, state: &mut H) {
- use std::hash::Hash;
-
- std::any::TypeId::of::<Self>().hash(state);
- self.0.hash(state);
- }
-
- fn stream(
- self: Box<Self>,
- _input: futures::stream::BoxStream<'static, E>,
- ) -> futures::stream::BoxStream<'static, Self::Output> {
- use futures::stream::StreamExt;
-
- smol::Timer::interval(self.0).boxed()
- }
-}
-
-#[cfg(feature = "async-std")]
-impl<H, E> subscription::Recipe<H, E> for Every
-where
- H: std::hash::Hasher,
-{
- type Output = std::time::Instant;
-
- fn hash(&self, state: &mut H) {
- use std::hash::Hash;
-
- std::any::TypeId::of::<Self>().hash(state);
- self.0.hash(state);
- }
-
- fn stream(
- self: Box<Self>,
- _input: futures::stream::BoxStream<'static, E>,
- ) -> futures::stream::BoxStream<'static, Self::Output> {
- use futures::stream::StreamExt;
-
- async_std::stream::interval(self.0)
- .map(|_| std::time::Instant::now())
- .boxed()
- }
-}
-
-#[cfg(all(
- feature = "tokio",
- not(any(feature = "async-std", feature = "smol"))
-))]
-impl<H, E> subscription::Recipe<H, E> for Every
-where
- H: std::hash::Hasher,
-{
- type Output = std::time::Instant;
-
- fn hash(&self, state: &mut H) {
- use std::hash::Hash;
-
- std::any::TypeId::of::<Self>().hash(state);
- self.0.hash(state);
- }
-
- fn stream(
- self: Box<Self>,
- _input: futures::stream::BoxStream<'static, E>,
- ) -> futures::stream::BoxStream<'static, Self::Output> {
- use futures::stream::StreamExt;
-
- let start = tokio::time::Instant::now() + self.0;
-
- let stream = {
- futures::stream::unfold(
- tokio::time::interval_at(start, self.0),
- |mut interval| async move {
- Some((interval.tick().await, interval))
- },
- )
- };
-
- stream.map(tokio::time::Instant::into_std).boxed()
- }
-}