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#[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#[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}