Skip to main content

agnostic_lite/
tokio.rs

1// TODO: remove this line when clippy fix the bug
2#![allow(clippy::needless_return)]
3
4cfg_time!(
5  mod after;
6  mod delay;
7  mod interval;
8  mod sleep;
9  mod timeout;
10
11  pub use after::*;
12  pub use delay::*;
13  pub use interval::*;
14  pub use sleep::*;
15  pub use timeout::*;
16
17  use core::time::Duration;
18);
19
20use core::future::Future;
21
22use crate::{AsyncBlockingSpawner, AsyncLocalSpawner, AsyncSpawner, Yielder};
23
24/// A [`AsyncSpawner`] that uses the [`tokio`] runtime.
25#[derive(Debug, Clone, Copy)]
26pub struct TokioSpawner;
27
28impl Yielder for TokioSpawner {
29  async fn yield_now() {
30    ::tokio::task::yield_now().await
31  }
32
33  async fn yield_now_local() {
34    ::tokio::task::yield_now().await
35  }
36}
37
38impl AsyncSpawner for TokioSpawner {
39  type JoinHandle<F>
40    = tokio::task::JoinHandle<F>
41  where
42    F: Send + 'static;
43
44  fn spawn<F>(future: F) -> Self::JoinHandle<F::Output>
45  where
46    F::Output: Send + 'static,
47    F: core::future::Future + Send + 'static,
48  {
49    ::tokio::task::spawn(future)
50  }
51}
52
53impl AsyncLocalSpawner for TokioSpawner {
54  type JoinHandle<F>
55    = ::tokio::task::JoinHandle<F>
56  where
57    F: 'static;
58
59  fn spawn_local<F>(future: F) -> Self::JoinHandle<F::Output>
60  where
61    F::Output: 'static,
62    F: core::future::Future + 'static,
63  {
64    tokio::task::spawn_local(future)
65  }
66}
67
68impl<T> super::JoinHandle<T> for ::tokio::task::JoinHandle<T> {
69  type JoinError = ::tokio::task::JoinError;
70
71  fn abort(self) {
72    Self::abort(&self)
73  }
74}
75
76impl<T> super::LocalJoinHandle<T> for ::tokio::task::JoinHandle<T> {
77  type JoinError = ::tokio::task::JoinError;
78}
79
80impl AsyncBlockingSpawner for TokioSpawner {
81  type JoinHandle<R>
82    = ::tokio::task::JoinHandle<R>
83  where
84    R: Send + 'static;
85
86  fn spawn_blocking<F, R>(_f: F) -> Self::JoinHandle<R>
87  where
88    F: FnOnce() -> R + Send + 'static,
89    R: Send + 'static,
90  {
91    #[cfg(not(target_family = "wasm"))]
92    {
93      ::tokio::task::spawn_blocking(_f)
94    }
95
96    #[cfg(target_family = "wasm")]
97    {
98      panic!("TokioRuntime::spawn_blocking is not supported on wasm")
99    }
100  }
101}
102
103/// Concrete [`RuntimeLite`](crate::RuntimeLite) implementation based on [`tokio`] runtime.
104///
105/// [`tokio`]: https://docs.rs/tokio
106#[derive(Debug, Clone, Copy)]
107pub struct TokioRuntime;
108
109impl core::fmt::Display for TokioRuntime {
110  fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
111    write!(f, "tokio")
112  }
113}
114
115impl super::LocalRuntimeLite for TokioRuntime {
116  type LocalSpawner = TokioSpawner;
117  type BlockingSpawner = TokioSpawner;
118
119  fn new() -> Self {
120    Self
121  }
122
123  fn name() -> &'static str {
124    "tokio"
125  }
126
127  fn fqname() -> &'static str {
128    "tokio"
129  }
130
131  fn block_on<F: Future>(f: F) -> F::Output {
132    ::tokio::runtime::Handle::current().block_on(f)
133  }
134
135  cfg_time!(
136    type Instant = ::tokio::time::Instant;
137
138    type LocalInterval = TokioInterval;
139    type LocalSleep = TokioSleep;
140    type LocalDelay<F>
141      = TokioDelay<F>
142    where
143      F: Future;
144    type LocalTimeout<F>
145      = TokioTimeout<F>
146    where
147      F: Future;
148  );
149
150  cfg_time!(
151    fn interval_local(interval: Duration) -> Self::LocalInterval {
152      use crate::time::AsyncIntervalExt;
153
154      TokioInterval::interval(interval)
155    }
156
157    fn interval_local_at(start: Self::Instant, period: Duration) -> Self::LocalInterval {
158      use crate::time::AsyncIntervalExt;
159
160      TokioInterval::interval_at(start, period)
161    }
162
163    fn sleep_local(duration: Duration) -> Self::LocalSleep {
164      use crate::time::AsyncSleepExt;
165
166      TokioSleep::sleep(duration)
167    }
168
169    fn sleep_local_until(instant: Self::Instant) -> Self::LocalSleep {
170      use crate::time::AsyncSleepExt;
171
172      TokioSleep::sleep_until(instant)
173    }
174
175    fn delay_local<F>(duration: Duration, fut: F) -> Self::LocalDelay<F>
176    where
177      F: Future,
178    {
179      use crate::time::AsyncLocalDelayExt;
180
181      <TokioDelay<F> as AsyncLocalDelayExt<F>>::delay(duration, fut)
182    }
183
184    fn delay_local_at<F>(deadline: Self::Instant, fut: F) -> Self::LocalDelay<F>
185    where
186      F: Future,
187    {
188      use crate::time::AsyncLocalDelayExt;
189
190      <TokioDelay<F> as AsyncLocalDelayExt<F>>::delay_at(deadline, fut)
191    }
192
193    fn timeout_local<F>(duration: Duration, future: F) -> Self::LocalTimeout<F>
194    where
195      F: Future,
196    {
197      use crate::time::AsyncLocalTimeout;
198
199      <TokioTimeout<F> as AsyncLocalTimeout<F>>::timeout_local(duration, future)
200    }
201
202    fn timeout_local_at<F>(deadline: Self::Instant, future: F) -> Self::LocalTimeout<F>
203    where
204      F: Future,
205    {
206      use crate::time::AsyncLocalTimeout;
207
208      <TokioTimeout<F> as AsyncLocalTimeout<F>>::timeout_local_at(deadline, future)
209    }
210  );
211}
212
213impl super::RuntimeLite for TokioRuntime {
214  type Spawner = TokioSpawner;
215
216  async fn yield_now() {
217    ::tokio::task::yield_now().await
218  }
219
220  cfg_time!(
221    type AfterSpawner = TokioSpawner;
222
223    type Interval = TokioInterval;
224    type Sleep = TokioSleep;
225    type Delay<F>
226      = TokioDelay<F>
227    where
228      F: Future + Send;
229    type Timeout<F>
230      = TokioTimeout<F>
231    where
232      F: Future + Send;
233  );
234
235  cfg_time!(
236    fn interval(interval: Duration) -> Self::Interval {
237      use crate::time::AsyncIntervalExt;
238
239      TokioInterval::interval(interval)
240    }
241
242    fn interval_at(start: Self::Instant, period: Duration) -> Self::Interval {
243      use crate::time::AsyncIntervalExt;
244
245      TokioInterval::interval_at(start, period)
246    }
247
248    fn sleep(duration: Duration) -> Self::Sleep {
249      use crate::time::AsyncSleepExt;
250
251      TokioSleep::sleep(duration)
252    }
253
254    fn sleep_until(instant: Self::Instant) -> Self::Sleep {
255      use crate::time::AsyncSleepExt;
256
257      TokioSleep::sleep_until(instant)
258    }
259
260    fn delay<F>(duration: Duration, fut: F) -> Self::Delay<F>
261    where
262      F: Future + Send,
263    {
264      use crate::time::AsyncDelayExt;
265
266      <TokioDelay<F> as AsyncDelayExt<F>>::delay(duration, fut)
267    }
268
269    fn delay_at<F>(deadline: Self::Instant, fut: F) -> Self::Delay<F>
270    where
271      F: Future + Send,
272    {
273      use crate::time::AsyncDelayExt;
274
275      <TokioDelay<F> as AsyncDelayExt<F>>::delay_at(deadline, fut)
276    }
277
278    fn timeout<F>(timeout: Duration, fut: F) -> Self::Timeout<F>
279    where
280      F: Future + Send,
281    {
282      use crate::time::AsyncTimeout;
283
284      <TokioTimeout<F> as AsyncTimeout<F>>::timeout(timeout, fut)
285    }
286
287    fn timeout_at<F>(deadline: Self::Instant, future: F) -> Self::Timeout<F>
288    where
289      F: Future + Send,
290    {
291      use crate::time::AsyncTimeout;
292
293      <TokioTimeout<F> as AsyncTimeout<F>>::timeout_at(deadline, future)
294    }
295  );
296}