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