async_rs/implementors/
smol.rs1use crate::{
4 Runtime,
5 sys::AsSysFd,
6 traits::{Executor, Reactor, RuntimeKit},
7 util::{IOHandle, Task},
8};
9use futures_core::Stream;
10use futures_io::{AsyncRead, AsyncWrite};
11use smol::{Async, Timer};
12use std::{
13 future::Future,
14 io::{self, Read, Write},
15 net::{SocketAddr, TcpStream},
16 time::{Duration, Instant},
17};
18
19use task::STask;
20
21pub type SmolRuntime = Runtime<Smol>;
23
24impl SmolRuntime {
25 #[must_use]
27 pub fn smol() -> Self {
28 Self::new(Smol)
29 }
30}
31
32#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
34pub struct Smol;
35
36impl RuntimeKit for Smol {}
37
38impl Executor for Smol {
39 type Task<T: Send + 'static> = STask<T>;
40
41 fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
42 smol::block_on(f)
43 }
44
45 fn spawn<T: Send + 'static, F: Future<Output = T> + Send + 'static>(
46 &self,
47 f: F,
48 ) -> Task<Self::Task<T>> {
49 STask(Some(smol::spawn(f))).into()
50 }
51
52 fn spawn_blocking<T: Send + 'static, F: FnOnce() -> T + Send + 'static>(
53 &self,
54 f: F,
55 ) -> Task<Self::Task<T>> {
56 STask(Some(smol::unblock(f))).into()
57 }
58}
59
60impl Reactor for Smol {
61 type TcpStream = Async<TcpStream>;
62 type Sleep = Timer;
63
64 fn register<H: Read + Write + AsSysFd + Send + 'static>(
65 &self,
66 socket: H,
67 ) -> io::Result<impl AsyncRead + AsyncWrite + Send + Unpin + 'static> {
68 Async::new(IOHandle::new(socket))
69 }
70
71 fn sleep(&self, dur: Duration) -> Self::Sleep {
72 Timer::after(dur)
73 }
74
75 fn interval(&self, dur: Duration) -> impl Stream<Item = Instant> + Send + 'static {
76 Timer::interval(dur)
77 }
78
79 fn tcp_connect_addr(
80 &self,
81 addr: SocketAddr,
82 ) -> impl Future<Output = io::Result<Self::TcpStream>> + Send + 'static {
83 async move {
84 let stream = Async::<TcpStream>::connect(addr).await?;
85 stream.get_ref().set_nodelay(true)?;
86 Ok(stream)
87 }
88 }
89}
90
91mod task {
92 use crate::util::TaskImpl;
93 use async_trait::async_trait;
94 use std::{
95 future::Future,
96 pin::Pin,
97 task::{Context, Poll},
98 };
99
100 #[derive(Debug)]
102 pub struct STask<T: Send + 'static>(pub(super) Option<smol::Task<T>>);
103
104 #[async_trait]
105 impl<T: Send + 'static> TaskImpl for STask<T> {
106 async fn cancel(&mut self) -> Option<T> {
107 self.0.take()?.cancel().await
108 }
109
110 fn detach(&mut self) {
111 if let Some(task) = self.0.take() {
112 task.detach();
113 }
114 }
115 }
116
117 impl<T: Send + 'static> Future for STask<T> {
118 type Output = T;
119
120 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
121 let task = self
124 .0
125 .as_mut()
126 .expect("Task polled after it was canceled or completed");
127 Pin::new(task).poll(cx)
128 }
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn auto_traits() {
138 use crate::util::test::*;
139 let runtime = Runtime::smol();
140 assert_send(&runtime);
141 assert_sync(&runtime);
142 assert_clone(&runtime);
143 }
144}