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(tokio::time::MissedTickBehavior::Skip);
46
47            let stream = {
48                futures::stream::unfold(interval, |mut interval| async move {
49                    Some((interval.tick().await, interval))
50                })
51            };
52
53            stream.map(tokio::time::Instant::into_std).boxed()
54        })
55    }
56
57    /// Returns a [`Subscription`] that runs the given async function at a
58    /// set interval; producing the result of the function as output.
59    pub fn repeat<F, T>(f: fn() -> F, interval: Duration) -> Subscription<T>
60    where
61        F: Future<Output = T> + MaybeSend + 'static,
62        T: MaybeSend + 'static,
63    {
64        Subscription::run_with((f, interval), |(f, interval)| {
65            let f = *f;
66            let interval = *interval;
67
68            stream::unfold(0, move |i| async move {
69                if i > 0 {
70                    tokio::time::sleep(interval).await;
71                }
72
73                Some((f().await, i + 1))
74            })
75        })
76    }
77}