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::RuntimeLite for TokioRuntime {
116  type Spawner = TokioSpawner;
117  type LocalSpawner = TokioSpawner;
118  type BlockingSpawner = TokioSpawner;
119
120  fn new() -> Self {
121    Self
122  }
123
124  fn name() -> &'static str {
125    "tokio"
126  }
127
128  fn fqname() -> &'static str {
129    "tokio"
130  }
131
132  fn block_on<F: Future>(f: F) -> F::Output {
133    ::tokio::runtime::Handle::current().block_on(f)
134  }
135
136  async fn yield_now() {
137    ::tokio::task::yield_now().await
138  }
139
140  cfg_time!(
141    type Instant = ::tokio::time::Instant;
142    type AfterSpawner = TokioSpawner;
143
144    type Interval = TokioInterval;
145    type LocalInterval = TokioInterval;
146    type Sleep = TokioSleep;
147    type LocalSleep = TokioSleep;
148    type Delay<F>
149      = TokioDelay<F>
150    where
151      F: Future + Send;
152    type LocalDelay<F>
153      = TokioDelay<F>
154    where
155      F: Future;
156    type Timeout<F>
157      = TokioTimeout<F>
158    where
159      F: Future + Send;
160    type LocalTimeout<F>
161      = TokioTimeout<F>
162    where
163      F: Future;
164  );
165
166  cfg_time!(
167    fn interval(interval: Duration) -> Self::Interval {
168      use crate::time::AsyncIntervalExt;
169
170      TokioInterval::interval(interval)
171    }
172
173    fn interval_at(start: Self::Instant, period: Duration) -> Self::Interval {
174      use crate::time::AsyncIntervalExt;
175
176      TokioInterval::interval_at(start, period)
177    }
178
179    fn interval_local(interval: Duration) -> Self::LocalInterval {
180      use crate::time::AsyncIntervalExt;
181
182      TokioInterval::interval(interval)
183    }
184
185    fn interval_local_at(start: Self::Instant, period: Duration) -> Self::LocalInterval {
186      use crate::time::AsyncIntervalExt;
187
188      TokioInterval::interval_at(start, period)
189    }
190
191    fn sleep(duration: Duration) -> Self::Sleep {
192      use crate::time::AsyncSleepExt;
193
194      TokioSleep::sleep(duration)
195    }
196
197    fn sleep_until(instant: Self::Instant) -> Self::Sleep {
198      use crate::time::AsyncSleepExt;
199
200      TokioSleep::sleep_until(instant)
201    }
202
203    fn sleep_local(duration: Duration) -> Self::LocalSleep {
204      use crate::time::AsyncSleepExt;
205
206      TokioSleep::sleep(duration)
207    }
208
209    fn sleep_local_until(instant: Self::Instant) -> Self::LocalSleep {
210      use crate::time::AsyncSleepExt;
211
212      TokioSleep::sleep_until(instant)
213    }
214
215    fn delay<F>(duration: Duration, fut: F) -> Self::Delay<F>
216    where
217      F: Future + Send,
218    {
219      use crate::time::AsyncDelayExt;
220
221      <TokioDelay<F> as AsyncDelayExt<F>>::delay(duration, fut)
222    }
223
224    fn delay_local<F>(duration: Duration, fut: F) -> Self::LocalDelay<F>
225    where
226      F: Future,
227    {
228      use crate::time::AsyncLocalDelayExt;
229
230      <TokioDelay<F> as AsyncLocalDelayExt<F>>::delay(duration, fut)
231    }
232
233    fn delay_at<F>(deadline: Self::Instant, fut: F) -> Self::Delay<F>
234    where
235      F: Future + Send,
236    {
237      use crate::time::AsyncDelayExt;
238
239      <TokioDelay<F> as AsyncDelayExt<F>>::delay_at(deadline, fut)
240    }
241
242    fn delay_local_at<F>(deadline: Self::Instant, fut: F) -> Self::LocalDelay<F>
243    where
244      F: Future,
245    {
246      use crate::time::AsyncLocalDelayExt;
247
248      <TokioDelay<F> as AsyncLocalDelayExt<F>>::delay_at(deadline, fut)
249    }
250
251    fn timeout<F>(timeout: Duration, fut: F) -> Self::Timeout<F>
252    where
253      F: Future + Send,
254    {
255      use crate::time::AsyncTimeout;
256
257      <TokioTimeout<F> as AsyncTimeout<F>>::timeout(timeout, fut)
258    }
259
260    fn timeout_at<F>(deadline: Self::Instant, future: F) -> Self::Timeout<F>
261    where
262      F: Future + Send,
263    {
264      use crate::time::AsyncTimeout;
265
266      <TokioTimeout<F> as AsyncTimeout<F>>::timeout_at(deadline, future)
267    }
268
269    fn timeout_local<F>(duration: Duration, future: F) -> Self::LocalTimeout<F>
270    where
271      F: Future,
272    {
273      use crate::time::AsyncLocalTimeout;
274
275      <TokioTimeout<F> as AsyncLocalTimeout<F>>::timeout_local(duration, future)
276    }
277
278    fn timeout_local_at<F>(deadline: Self::Instant, future: F) -> Self::LocalTimeout<F>
279    where
280      F: Future,
281    {
282      use crate::time::AsyncLocalTimeout;
283
284      <TokioTimeout<F> as AsyncLocalTimeout<F>>::timeout_local_at(deadline, future)
285    }
286  );
287}