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 {
64 type JoinHandle<O>
65 = JoinHandle<O>
66 where
67 O: 'static;
68
69 fn spawn_local<F>(_future: F) -> Self::JoinHandle<F::Output>
70 where
71 F::Output: 'static,
72 F: Future + 'static,
73 {
74 panic!(
75 "agnostic-lite: smol has no ambient thread-local executor to spawn onto; drive a \
76 smol::LocalExecutor yourself and spawn onto it directly"
77 )
78 }
79
80 fn spawn_local_detach<F>(_future: F)
81 where
82 F::Output: 'static,
83 F: Future + 'static,
84 {
85 panic!(
86 "agnostic-lite: smol has no ambient thread-local executor to spawn onto; drive a \
87 smol::LocalExecutor yourself and spawn onto it directly"
88 )
89 }
90}
91
92join_handle!(::smol::Task<T>);
93
94impl<T> super::JoinHandle<T> for JoinHandle<T> {
95 type JoinError = super::spawner::handle::JoinError;
96
97 fn detach(self) {
98 ::smol::Task::detach(self.handle)
99 }
100
101 fn abort(self) {
102 drop(self);
103 }
104}
105
106impl<T> super::LocalJoinHandle<T> for JoinHandle<T> {
107 type JoinError = super::spawner::handle::JoinError;
108
109 fn detach(self) {
110 ::smol::Task::detach(self.handle)
111 }
112}
113
114impl AsyncBlockingSpawner for SmolSpawner {
115 type JoinHandle<R>
116 = JoinHandle<R>
117 where
118 R: Send + 'static;
119
120 fn spawn_blocking<F, R>(f: F) -> Self::JoinHandle<R>
121 where
122 F: FnOnce() -> R + Send + 'static,
123 R: Send + 'static,
124 {
125 ::smol::unblock(f).into()
126 }
127
128 fn spawn_blocking_detach<F, R>(f: F)
129 where
130 F: FnOnce() -> R + Send + 'static,
131 R: Send + 'static,
132 {
133 ::smol::unblock(f).detach()
134 }
135}
136
137#[derive(Debug, Clone, Copy)]
141pub struct SmolRuntime;
142
143impl core::fmt::Display for SmolRuntime {
144 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
145 write!(f, "smol")
146 }
147}
148
149impl super::LocalRuntimeLite for SmolRuntime {
150 type LocalSpawner = SmolSpawner;
151 type BlockingSpawner = SmolSpawner;
152
153 cfg_time!(
154 type Instant = Instant;
155 type LocalInterval = AsyncIoInterval;
156 type LocalSleep = AsyncIoSleep;
157 type LocalDelay<F>
158 = AsyncIoDelay<F>
159 where
160 F: Future;
161 type LocalTimeout<F>
162 = AsyncIoTimeout<F>
163 where
164 F: Future;
165 );
166
167 fn new() -> Self {
168 Self
169 }
170
171 fn name() -> &'static str {
172 "smol"
173 }
174
175 fn fqname() -> &'static str {
176 "smol"
177 }
178
179 fn block_on<F: Future>(f: F) -> F::Output {
180 ::smol::block_on(f)
181 }
182
183 cfg_time!(
184 fn interval_local(interval: Duration) -> Self::LocalInterval {
185 AsyncIoInterval::interval(interval)
186 }
187
188 fn interval_local_at(start: Instant, period: Duration) -> Self::LocalInterval {
189 AsyncIoInterval::interval_at(start, period)
190 }
191
192 fn sleep_local(duration: Duration) -> Self::LocalSleep {
193 use crate::time::AsyncSleepExt;
194
195 AsyncIoSleep::sleep(duration)
196 }
197
198 fn sleep_local_until(instant: Instant) -> Self::LocalSleep {
199 use crate::time::AsyncSleepExt;
200
201 AsyncIoSleep::sleep_until(instant)
202 }
203
204 fn delay_local<F>(duration: Duration, fut: F) -> Self::LocalDelay<F>
205 where
206 F: Future,
207 {
208 use crate::time::AsyncLocalDelayExt;
209
210 <AsyncIoDelay<F> as AsyncLocalDelayExt<F>>::delay(duration, fut)
211 }
212
213 fn delay_local_at<F>(deadline: Instant, fut: F) -> Self::LocalDelay<F>
214 where
215 F: Future,
216 {
217 use crate::time::AsyncLocalDelayExt;
218
219 <AsyncIoDelay<F> as AsyncLocalDelayExt<F>>::delay_at(deadline, fut)
220 }
221
222 fn timeout_local<F>(duration: Duration, future: F) -> Self::LocalTimeout<F>
223 where
224 F: Future,
225 {
226 use crate::time::AsyncLocalTimeout;
227
228 <AsyncIoTimeout<F> as AsyncLocalTimeout<F>>::timeout_local(duration, future)
229 }
230
231 fn timeout_local_at<F>(deadline: Instant, future: F) -> Self::LocalTimeout<F>
232 where
233 F: Future,
234 {
235 use crate::time::AsyncLocalTimeout;
236
237 <AsyncIoTimeout<F> as AsyncLocalTimeout<F>>::timeout_local_at(deadline, future)
238 }
239 );
240}
241
242impl super::RuntimeLite for SmolRuntime {
243 type Spawner = SmolSpawner;
244
245 cfg_time!(
246 type AfterSpawner = SmolSpawner;
247 type Interval = AsyncIoInterval;
248 type Sleep = AsyncIoSleep;
249 type Delay<F>
250 = AsyncIoDelay<F>
251 where
252 F: Future + Send;
253 type Timeout<F>
254 = AsyncIoTimeout<F>
255 where
256 F: Future + Send;
257 );
258
259 async fn yield_now() {
260 ::smol::future::yield_now().await
261 }
262
263 cfg_time!(
264 fn interval(interval: Duration) -> Self::Interval {
265 AsyncIoInterval::interval(interval)
266 }
267
268 fn interval_at(start: Instant, period: Duration) -> Self::Interval {
269 AsyncIoInterval::interval_at(start, period)
270 }
271
272 fn sleep(duration: Duration) -> Self::Sleep {
273 use crate::time::AsyncSleepExt;
274
275 AsyncIoSleep::sleep(duration)
276 }
277
278 fn sleep_until(instant: Instant) -> Self::Sleep {
279 use crate::time::AsyncSleepExt;
280
281 AsyncIoSleep::sleep_until(instant)
282 }
283
284 fn delay<F>(duration: Duration, fut: F) -> Self::Delay<F>
285 where
286 F: Future + Send,
287 {
288 use crate::time::AsyncDelayExt;
289
290 <AsyncIoDelay<F> as AsyncDelayExt<F>>::delay(duration, fut)
291 }
292
293 fn delay_at<F>(deadline: Instant, fut: F) -> Self::Delay<F>
294 where
295 F: Future + Send,
296 {
297 use crate::time::AsyncDelayExt;
298
299 <AsyncIoDelay<F> as AsyncDelayExt<F>>::delay_at(deadline, fut)
300 }
301
302 fn timeout<F>(duration: Duration, future: F) -> Self::Timeout<F>
303 where
304 F: Future + Send,
305 {
306 use crate::time::AsyncTimeout;
307
308 <AsyncIoTimeout<F> as AsyncTimeout<F>>::timeout(duration, future)
309 }
310
311 fn timeout_at<F>(deadline: Instant, future: F) -> Self::Timeout<F>
312 where
313 F: Future + Send,
314 {
315 use crate::time::AsyncTimeout;
316
317 <AsyncIoTimeout<F> as AsyncTimeout<F>>::timeout_at(deadline, future)
318 }
319 );
320}