agnostic_lite/
smol.rs

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