iced_futures/backend/native/
tokio.rs

1//! A `tokio` backend.
2
3/// A `tokio` executor.
4pub type Executor = tokio::runtime::Runtime;
5
6impl crate::Executor for Executor {
7    fn new() -> Result<Self, futures::io::Error> {
8        tokio::runtime::Runtime::new()
9    }
10
11    #[allow(clippy::let_underscore_future)]
12    fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
13        let _ = tokio::runtime::Runtime::spawn(self, future);
14    }
15
16    fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
17        let _guard = tokio::runtime::Runtime::enter(self);
18        f()
19    }
20}
21
22pub mod time {
23    //! Listen and react to time.
24    use crate::MaybeSend;
25    use crate::core::time::{Duration, Instant};
26    use crate::subscription::Subscription;
27
28    use futures::stream;
29
30    /// Returns a [`Subscription`] that produces messages at a set interval.
31    ///
32    /// The first message is produced after a `duration`, and then continues to
33    /// produce more messages every `duration` after that.
34    pub fn every(duration: Duration) -> Subscription<Instant> {
35        Subscription::run_with(duration, |duration| {
36            use futures::stream::StreamExt;
37
38            let start = tokio::time::Instant::now() + *duration;
39
40            let mut interval = tokio::time::interval_at(start, *duration);
41            interval.set_missed_tick_behavior(
42                tokio::time::MissedTickBehavior::Skip,
43            );
44
45            let stream = {
46                futures::stream::unfold(interval, |mut interval| async move {
47                    Some((interval.tick().await, interval))
48                })
49            };
50
51            stream.map(tokio::time::Instant::into_std).boxed()
52        })
53    }
54
55    /// Returns a [`Subscription`] that runs the given async function at a
56    /// set interval; producing the result of the function as output.
57    pub fn repeat<F, T>(f: fn() -> F, interval: Duration) -> Subscription<T>
58    where
59        F: Future<Output = T> + MaybeSend + 'static,
60        T: MaybeSend + 'static,
61    {
62        Subscription::run_with((f, interval), |(f, interval)| {
63            let f = *f;
64            let interval = *interval;
65
66            stream::unfold(0, move |i| async move {
67                if i > 0 {
68                    tokio::time::sleep(interval).await;
69                }
70
71                Some((f().await, i + 1))
72            })
73        })
74    }
75}