From e2076612cb98d04a8a48add14d0068c2974d5653 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 30 Apr 2020 05:37:44 +0200 Subject: Implement `time::every` in `iced_futures` --- futures/src/time.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 futures/src/time.rs (limited to 'futures/src/time.rs') diff --git a/futures/src/time.rs b/futures/src/time.rs new file mode 100644 index 00000000..e87b4a83 --- /dev/null +++ b/futures/src/time.rs @@ -0,0 +1,70 @@ +//! 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. +/// +/// [`Subscription`]: ../subscription/struct.Subscription.html +pub fn every( + duration: std::time::Duration, +) -> Subscription { + Subscription::from_recipe(Every(duration)) +} + +struct Every(std::time::Duration); + +#[cfg(feature = "async-std")] +impl subscription::Recipe 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::().hash(state); + self.0.hash(state); + } + + fn stream( + self: Box, + _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(feature = "async-std")))] +impl subscription::Recipe 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::().hash(state); + self.0.hash(state); + } + + fn stream( + self: Box, + _input: futures::stream::BoxStream<'static, E>, + ) -> futures::stream::BoxStream<'static, Self::Output> { + use futures::stream::StreamExt; + + let start = tokio::time::Instant::now() + self.0; + + tokio::time::interval_at(start, self.0) + .map(|_| std::time::Instant::now()) + .boxed() + } +} -- cgit