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    fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
22        self.block_on(future)
23    }
24}
25
26pub mod time {
27    //! Listen and react to time.
28    use crate::MaybeSend;
29    use crate::core::time::{Duration, Instant};
30    use crate::subscription::Subscription;
31
32    use futures::stream;
33
34    /// Returns a [`Subscription`] that produces messages at a set interval.
35    ///
36    /// The first message is produced after a `duration`, and then continues to
37    /// produce more messages every `duration` after that.
38    pub fn every(duration: Duration) -> Subscription<Instant> {
39        Subscription::run_with(duration, |duration| {
40            use futures::stream::StreamExt;
41
42            let start = tokio::time::Instant::now() + *duration;
43
44            let mut interval = tokio::time::interval_at(start, *duration);
45            interval.set_missed_tick_behavior(
46                tokio::time::MissedTickBehavior::Skip,
47            );
48
49            let stream = {
50                futures::stream::unfold(interval, |mut interval| async move {
51                    Some((interval.tick().await, interval))
52                })
53            };
54
55            stream.map(tokio::time::Instant::into_std).boxed()
56        })
57    }
58
59    /// Returns a [`Subscription`] that runs the given async function at a
60    /// set interval; producing the result of the function as output.
61    pub fn repeat<F, T>(f: fn() -> F, interval: Duration) -> Subscription<T>
62    where
63        F: Future<Output = T> + MaybeSend + 'static,
64        T: MaybeSend + 'static,
65    {
66        Subscription::run_with((f, interval), |(f, interval)| {
67            let f = *f;
68            let interval = *interval;
69
70            stream::unfold(0, move |i| async move {
71                if i > 0 {
72                    tokio::time::sleep(interval).await;
73                }
74
75                Some((f().await, i + 1))
76            })
77        })
78    }
79}