executor_core/
tokio.rs

1use crate::{Error, Executor, LocalTask, Task};
2use alloc::string::ToString;
3use std::{
4    pin::Pin,
5    task::{Poll, ready},
6};
7
8impl Executor for tokio::runtime::Runtime {
9    fn spawn<T: Send + 'static>(
10        &self,
11        fut: impl Future<Output = T> + Send + 'static,
12    ) -> impl Task<Output = T> {
13        TokioTask(tokio::runtime::Runtime::spawn(self, fut))
14    }
15}
16
17struct TokioTask<T>(tokio::task::JoinHandle<T>);
18
19impl<T: 'static> LocalTask for TokioTask<T> {
20    async fn result(self) -> Result<Self::Output, crate::Error> {
21        self.0.await.map_err(|error| {
22            if let Err(panic) = error.try_into_panic() {
23                Error::Panicked(panic.to_string().into())
24            } else {
25                Error::Cancelled
26            }
27        })
28    }
29    fn cancel(self) {
30        self.0.abort();
31    }
32}
33
34impl<T: 'static + Send> Task for TokioTask<T> {
35    async fn result(self) -> Result<Self::Output, crate::Error> {
36        self.0.await.map_err(|error| {
37            if let Err(panic) = error.try_into_panic() {
38                Error::Panicked(panic.to_string().into())
39            } else {
40                Error::Cancelled
41            }
42        })
43    }
44    fn cancel(self) {
45        self.0.abort();
46    }
47}
48
49impl<T> Future for TokioTask<T> {
50    type Output = T;
51    fn poll(
52        mut self: std::pin::Pin<&mut Self>,
53        cx: &mut std::task::Context<'_>,
54    ) -> std::task::Poll<Self::Output> {
55        let result = ready!(Pin::new(&mut self.0).poll(cx));
56
57        Poll::Ready(result.unwrap())
58    }
59}