1pub use internal::{DefaultExecutor, Runtime, TaskExecutor};
5
6use std::future::Future;
7use std::pin::Pin;
8
9pub trait Executor: Send + Sync + 'static + Clone {
15    fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>);
21}
22
23#[cfg(all(feature = "tokio", not(feature = "async-std")))]
24mod internal {
25    use super::*;
26
27    pub struct Runtime {
29        rt: tokio::runtime::Runtime,
30        spawner: TaskExecutor,
31    }
32
33    impl Runtime {
34        pub fn new() -> Option<Self> {
36            Some(Runtime {
37                rt: tokio::runtime::Runtime::new().unwrap(),
38                spawner: TaskExecutor,
39            })
40        }
41
42        pub fn handle(&self) -> &TaskExecutor {
44            &self.spawner
45        }
46
47        pub fn block_on<F, T>(&mut self, future: F) -> T
50        where
51            F: Future<Output = T>,
52        {
53            self.rt.block_on(future)
54        }
55
56        pub fn spawn<F, T>(&self, future: F)
58        where
59            F: Future<Output = T> + Send + 'static,
60            T: Send + 'static,
61        {
62            self.rt.spawn(future);
63        }
64    }
65
66    #[derive(Clone)]
68    pub struct TaskExecutor;
69
70    impl TaskExecutor {
71        pub fn spawn<F>(&self, future: F)
73        where
74            F: Future + Send + 'static,
75            F::Output: Send + 'static,
76        {
77            tokio::spawn(future);
78        }
79    }
80
81    #[derive(Clone)]
82    pub struct DefaultExecutor;
84
85    impl DefaultExecutor {
86        pub fn current() -> Self {
88            Self {}
89        }
90    }
91
92    impl Executor for DefaultExecutor {
93        fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
94            tokio::spawn(future);
95        }
96    }
97}
98
99#[cfg(feature = "async-std")]
100mod internal {
101    use super::*;
102    use async_std::task;
103
104    #[derive(Clone)]
106    pub struct TaskExecutor;
107
108    impl TaskExecutor {
109        pub fn spawn<F>(&self, future: F)
111        where
112            F: Future + Send + 'static,
113            F::Output: Send + 'static,
114        {
115            task::spawn(future);
116        }
117    }
118
119    pub struct Runtime(TaskExecutor);
121
122    impl Runtime {
123        pub fn new() -> Option<Self> {
125            Some(Runtime(TaskExecutor))
126        }
127
128        pub fn handle(&self) -> &TaskExecutor {
130            &self.0
131        }
132
133        pub fn block_on<F, T>(&mut self, future: F) -> T
136        where
137            F: Future<Output = T>,
138        {
139            task::block_on(future)
140        }
141
142        pub fn spawn<F, T>(&self, future: F)
144        where
145            F: Future<Output = T> + Send + 'static,
146            T: Send + 'static,
147        {
148            task::spawn(future);
149        }
150    }
151
152    #[derive(Clone)]
154    pub struct DefaultExecutor;
155
156    impl DefaultExecutor {
157        pub fn current() -> Self {
159            Self {}
160        }
161    }
162
163    impl Executor for DefaultExecutor {
164        fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
165            task::spawn(future);
166        }
167    }
168}