1#![forbid(unsafe_code)]
4#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
5#![no_std]
6extern crate alloc;
7
8use alloc::boxed::Box;
9use async_trait::async_trait;
10use core::{fmt, future::Future, ops::Deref, pin::Pin};
11
12pub struct LocalExecutorError(pub Pin<Box<dyn Future<Output = ()>>>);
15
16impl fmt::Debug for LocalExecutorError {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_tuple("LocalExecutorError")
19 .field(&"Future")
20 .finish()
21 }
22}
23
24#[async_trait]
26pub trait Executor {
27 fn block_on(&self, f: Pin<Box<dyn Future<Output = ()>>>);
29
30 fn spawn(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) -> Box<dyn Task>;
32
33 fn spawn_local(
35 &self,
36 f: Pin<Box<dyn Future<Output = ()>>>,
37 ) -> Result<Box<dyn Task>, LocalExecutorError> {
38 Err(LocalExecutorError(f))
39 }
40
41 async fn spawn_blocking(&self, f: Box<dyn FnOnce() + Send + 'static>);
43}
44
45#[async_trait]
46impl<E: Deref + Sync> Executor for E
47where
48 E::Target: Executor + Sync,
49{
50 fn block_on(&self, f: Pin<Box<dyn Future<Output = ()>>>) {
51 self.deref().block_on(f)
52 }
53
54 fn spawn(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) -> Box<dyn Task> {
55 self.deref().spawn(f)
56 }
57
58 fn spawn_local(
59 &self,
60 f: Pin<Box<dyn Future<Output = ()>>>,
61 ) -> Result<Box<dyn Task>, LocalExecutorError> {
62 self.deref().spawn_local(f)
63 }
64
65 async fn spawn_blocking(&self, f: Box<dyn FnOnce() + Send + 'static>) {
66 self.deref().spawn_blocking(f).await
67 }
68}
69
70#[async_trait(?Send)]
72pub trait Task: Future<Output = ()> {
73 async fn cancel(self: Box<Self>) -> Option<()>;
78}