1use crate::impls::tokio::TokioRuntimeHandle as Handle;
3
4use crate::{CompoundRuntime, RealCoarseTimeProvider, ToplevelBlockOn};
5use std::io::{Error as IoError, ErrorKind, Result as IoResult};
6
7#[cfg(feature = "native-tls")]
8use crate::impls::native_tls::NativeTlsProvider;
9#[cfg(feature = "rustls")]
10use crate::impls::rustls::RustlsProvider;
11
12#[cfg(feature = "native-tls")]
22pub use TokioNativeTlsRuntime as PreferredRuntime;
23#[cfg(all(feature = "rustls", not(feature = "native-tls")))]
24pub use TokioRustlsRuntime as PreferredRuntime;
25
26#[derive(Clone)]
34#[cfg(feature = "native-tls")]
35pub struct TokioNativeTlsRuntime {
36 inner: HandleInner,
38}
39
40#[cfg(feature = "native-tls")]
42type HandleInner = CompoundRuntime<
43 Handle,
44 Handle,
45 RealCoarseTimeProvider,
46 Handle,
47 Handle,
48 NativeTlsProvider,
49 Handle,
50>;
51
52#[derive(Clone)]
54#[cfg(feature = "rustls")]
55pub struct TokioRustlsRuntime {
56 inner: RustlsHandleInner,
58}
59
60#[cfg(feature = "rustls")]
62type RustlsHandleInner =
63 CompoundRuntime<Handle, Handle, RealCoarseTimeProvider, Handle, Handle, RustlsProvider, Handle>;
64
65#[cfg(feature = "native-tls")]
66crate::opaque::implement_opaque_runtime! {
67 TokioNativeTlsRuntime { inner : HandleInner }
68}
69
70#[cfg(feature = "rustls")]
71crate::opaque::implement_opaque_runtime! {
72 TokioRustlsRuntime { inner : RustlsHandleInner }
73}
74
75#[cfg(feature = "native-tls")]
76impl From<tokio_crate::runtime::Handle> for TokioNativeTlsRuntime {
77 fn from(h: tokio_crate::runtime::Handle) -> Self {
78 let h = Handle::new(h);
79 TokioNativeTlsRuntime {
80 inner: CompoundRuntime::new(
81 h.clone(),
82 h.clone(),
83 RealCoarseTimeProvider::new(),
84 h.clone(),
85 h.clone(),
86 NativeTlsProvider::default(),
87 h,
88 ),
89 }
90 }
91}
92
93#[cfg(feature = "rustls")]
94impl From<tokio_crate::runtime::Handle> for TokioRustlsRuntime {
95 fn from(h: tokio_crate::runtime::Handle) -> Self {
96 let h = Handle::new(h);
97 TokioRustlsRuntime {
98 inner: CompoundRuntime::new(
99 h.clone(),
100 h.clone(),
101 RealCoarseTimeProvider::new(),
102 h.clone(),
103 h.clone(),
104 RustlsProvider::default(),
105 h,
106 ),
107 }
108 }
109}
110
111#[cfg(feature = "native-tls")]
112impl TokioNativeTlsRuntime {
113 pub fn create() -> IoResult<Self> {
121 crate::impls::tokio::create_runtime().map(|r| TokioNativeTlsRuntime {
122 inner: CompoundRuntime::new(
123 r.clone(),
124 r.clone(),
125 RealCoarseTimeProvider::new(),
126 r.clone(),
127 r.clone(),
128 NativeTlsProvider::default(),
129 r,
130 ),
131 })
132 }
133
134 pub fn current() -> IoResult<Self> {
148 Ok(current_handle()?.into())
149 }
150
151 #[doc(hidden)]
161 pub fn run_test<P, F, O>(func: P) -> O
162 where
163 P: FnOnce(Self) -> F,
164 F: futures::Future<Output = O>,
165 {
166 let runtime = Self::create().expect("Failed to create runtime");
167 runtime.clone().block_on(func(runtime))
168 }
169}
170
171#[cfg(feature = "rustls")]
172impl TokioRustlsRuntime {
173 pub fn create() -> IoResult<Self> {
181 crate::impls::tokio::create_runtime().map(|r| TokioRustlsRuntime {
182 inner: CompoundRuntime::new(
183 r.clone(),
184 r.clone(),
185 RealCoarseTimeProvider::new(),
186 r.clone(),
187 r.clone(),
188 RustlsProvider::default(),
189 r,
190 ),
191 })
192 }
193
194 pub fn current() -> IoResult<Self> {
208 Ok(current_handle()?.into())
209 }
210
211 #[doc(hidden)]
221 pub fn run_test<P, F, O>(func: P) -> O
222 where
223 P: FnOnce(Self) -> F,
224 F: futures::Future<Output = O>,
225 {
226 let runtime = Self::create().expect("Failed to create runtime");
227 runtime.clone().block_on(func(runtime))
228 }
229}
230
231#[cfg(any(feature = "native-tls", feature = "rustls"))]
233fn current_handle() -> std::io::Result<tokio_crate::runtime::Handle> {
234 tokio_crate::runtime::Handle::try_current().map_err(|e| IoError::new(ErrorKind::Other, e))
235}
236
237#[cfg(all(
238 test,
239 not(miri), ))]
241mod test {
242 #![allow(clippy::bool_assert_comparison)]
244 #![allow(clippy::clone_on_copy)]
245 #![allow(clippy::dbg_macro)]
246 #![allow(clippy::mixed_attributes_style)]
247 #![allow(clippy::print_stderr)]
248 #![allow(clippy::print_stdout)]
249 #![allow(clippy::single_char_pattern)]
250 #![allow(clippy::unwrap_used)]
251 #![allow(clippy::unchecked_duration_subtraction)]
252 #![allow(clippy::useless_vec)]
253 #![allow(clippy::needless_pass_by_value)]
254 use super::*;
256
257 #[test]
258 fn no_current() {
259 #[cfg(feature = "native-tls")]
262 assert!(TokioNativeTlsRuntime::current().is_err());
263
264 #[cfg(feature = "rustls")]
265 assert!(TokioRustlsRuntime::current().is_err());
266 }
267
268 #[test]
269 fn current() {
270 let runtime = PreferredRuntime::create().unwrap();
272 runtime.block_on(async {
273 #[cfg(feature = "native-tls")]
274 assert!(TokioNativeTlsRuntime::current().is_ok());
275
276 #[cfg(feature = "rustls")]
277 assert!(TokioRustlsRuntime::current().is_ok());
278 });
279 }
280
281 #[test]
282 fn debug() {
283 #[cfg(feature = "native-tls")]
284 assert_eq!(
285 format!("{:?}", TokioNativeTlsRuntime::create().unwrap()),
286 "TokioNativeTlsRuntime { .. }"
287 );
288 #[cfg(feature = "rustls")]
289 assert_eq!(
290 format!("{:?}", TokioRustlsRuntime::create().unwrap()),
291 "TokioRustlsRuntime { .. }"
292 );
293
294 assert_eq!(
296 format!("{:?}", PreferredRuntime::create().unwrap().inner),
297 "CompoundRuntime { .. }"
298 );
299 }
300}