1use async_scoped::spawner::{Blocker, FuncSpawner, Spawner};
15use futures::Future;
16
17pub(crate) mod abort;
18
19pub trait Runtime: 'static {
21 type ScopedSpawner: Spawner<()>
23 + FuncSpawner<(), SpawnHandle = <Self::ScopedSpawner as Spawner<()>>::SpawnHandle>
24 + Blocker
25 + Default
26 + Send
27 + Sync
28 + 'static;
29
30 type BlockingRunner: BlockingRunner;
32}
33
34pub trait BlockingRunner: 'static {
36 fn block_on<F: Future>(fut: F) -> F::Output;
38}
39
40#[cfg(feature = "tokio")]
42#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
43#[allow(missing_debug_implementations)]
44pub enum Tokio {}
45
46#[cfg(feature = "tokio")]
48#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
49pub mod tokio {
50 #![allow(missing_debug_implementations)]
51 use super::*;
52
53 impl Runtime for Tokio {
54 type ScopedSpawner = async_scoped::spawner::use_tokio::Tokio;
55 type BlockingRunner = TokioBlockingRunner;
56 }
57
58 pub struct TokioBlockingRunner;
60 impl BlockingRunner for TokioBlockingRunner {
61 fn block_on<F: Future>(fut: F) -> F::Output {
62 ::tokio::runtime::Handle::current().block_on(fut)
63 }
64 }
65}
66
67#[cfg(feature = "async-std")]
69#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
70#[allow(missing_debug_implementations)]
71pub enum AsyncStd {}
72
73#[cfg(feature = "async-std")]
75#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
76pub mod async_std {
77 #![allow(missing_debug_implementations)]
78 use super::*;
79
80 impl Runtime for AsyncStd {
81 type ScopedSpawner = async_scoped::spawner::use_async_std::AsyncStd;
82 type BlockingRunner = AsyncStdBlockingRunner;
83 }
84
85 pub struct AsyncStdBlockingRunner;
87 impl BlockingRunner for AsyncStdBlockingRunner {
88 fn block_on<F: Future>(fut: F) -> F::Output {
89 ::async_std::task::block_on(fut)
90 }
91 }
92}
93
94#[cfg(feature = "smol")]
96#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
97#[allow(missing_debug_implementations)]
98pub enum Smol {}
99
100#[cfg(feature = "smol")]
102#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
103pub mod smol {
104 #![allow(missing_debug_implementations)]
105 use super::*;
106
107 impl Runtime for Smol {
108 type ScopedSpawner = SmolScopedSpawner;
109 type BlockingRunner = SmolBlockingRunner;
110 }
111
112 #[derive(Default)]
114 #[allow(missing_debug_implementations)]
115 pub struct SmolScopedSpawner;
116 unsafe impl<T: Send + 'static> Spawner<T> for SmolScopedSpawner {
117 type FutureOutput = T;
118 type SpawnHandle = ::smol::Task<T>;
119
120 fn spawn<F: Future<Output = T> + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
121 ::smol::spawn(f)
122 }
123 }
124 unsafe impl<T: Send + 'static> FuncSpawner<T> for SmolScopedSpawner {
125 type FutureOutput = T;
126 type SpawnHandle = ::smol::Task<T>;
127
128 fn spawn_func<F: FnOnce() -> T + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
129 ::smol::unblock(f)
130 }
131 }
132 unsafe impl Blocker for SmolScopedSpawner {
133 fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
134 ::smol::block_on(f)
135 }
136 }
137
138 pub struct SmolBlockingRunner;
140 impl BlockingRunner for SmolBlockingRunner {
141 fn block_on<F: Future>(fut: F) -> F::Output {
142 ::smol::block_on(fut)
143 }
144 }
145}