1//! Entry points for use with async_std runtimes.
2pub use crate::impls::async_std::create_runtime as create_runtime_impl;
3use crate::{compound::CompoundRuntime, RealCoarseTimeProvider, ToplevelBlockOn};
4use std::io::Result as IoResult;
56#[cfg(feature = "native-tls")]
7use crate::impls::native_tls::NativeTlsProvider;
8#[cfg(feature = "rustls")]
9use crate::impls::rustls::RustlsProvider;
1011use async_executors::AsyncStd;
1213/// An alias for the async_std runtime that we prefer to use, based on whatever TLS
14/// implementation has been enabled.
15///
16/// If only one of `native_tls` and `rustls` bas been enabled within the
17/// `tor-rtcompat` crate, that will be the TLS backend that this uses.
18///
19/// Currently, `native_tls` is preferred over `rustls` when both are available,
20/// because of its maturity within Arti. However, this might change in the
21/// future.
22#[cfg(feature = "native-tls")]
23pub use AsyncStdNativeTlsRuntime as PreferredRuntime;
2425#[cfg(all(feature = "rustls", not(feature = "native-tls")))]
26pub use AsyncStdRustlsRuntime as PreferredRuntime;
2728/// A [`Runtime`](crate::Runtime) powered by `async_std` and `native_tls`.
29#[derive(Clone)]
30#[cfg(feature = "native-tls")]
31pub struct AsyncStdNativeTlsRuntime {
32/// The actual runtime object.
33inner: NativeTlsInner,
34}
3536/// Implementation type for AsyncStdRuntime.
37#[cfg(feature = "native-tls")]
38type NativeTlsInner = CompoundRuntime<
39 AsyncStd,
40 AsyncStd,
41 RealCoarseTimeProvider,
42 AsyncStd,
43 AsyncStd,
44 NativeTlsProvider,
45 AsyncStd,
46>;
4748#[cfg(feature = "native-tls")]
49crate::opaque::implement_opaque_runtime! {
50 AsyncStdNativeTlsRuntime { inner : NativeTlsInner }
51}
5253#[cfg(feature = "rustls")]
54/// A [`Runtime`](crate::Runtime) powered by `async_std` and `rustls`.
55#[derive(Clone)]
56pub struct AsyncStdRustlsRuntime {
57/// The actual runtime object.
58inner: RustlsInner,
59}
6061/// Implementation type for AsyncStdRustlsRuntime.
62#[cfg(feature = "rustls")]
63type RustlsInner = CompoundRuntime<
64 AsyncStd,
65 AsyncStd,
66 RealCoarseTimeProvider,
67 AsyncStd,
68 AsyncStd,
69 RustlsProvider,
70 AsyncStd,
71>;
7273#[cfg(feature = "rustls")]
74crate::opaque::implement_opaque_runtime! {
75 AsyncStdRustlsRuntime { inner: RustlsInner }
76}
7778#[cfg(feature = "native-tls")]
79impl AsyncStdNativeTlsRuntime {
80/// Return a new [`AsyncStdNativeTlsRuntime`]
81 ///
82 /// Generally you should call this function only once, and then use
83 /// [`Clone::clone()`] to create additional references to that
84 /// runtime.
85pub fn create() -> IoResult<Self> {
86let rt = create_runtime_impl();
87let ct = RealCoarseTimeProvider::new();
88Ok(AsyncStdNativeTlsRuntime {
89 inner: CompoundRuntime::new(rt, rt, ct, rt, rt, NativeTlsProvider::default(), rt),
90 })
91 }
9293/// Return an [`AsyncStdNativeTlsRuntime`] for the currently running
94 /// `async_std` executor.
95 ///
96 /// Note that since async_std executors are global, there is no distinction
97 /// between this method and [`AsyncStdNativeTlsRuntime::create()`]: it is
98 /// provided only for API consistency with the Tokio runtimes.
99pub fn current() -> IoResult<Self> {
100Self::create()
101 }
102103/// Helper to run a single test function in a freshly created runtime.
104 ///
105 /// # Panics
106 ///
107 /// Panics if we can't create this runtime.
108 ///
109 /// # Warning
110 ///
111 /// This API is **NOT** for consumption outside Arti. Semver guarantees are not provided.
112#[doc(hidden)]
113pub fn run_test<P, F, O>(func: P) -> O
114where
115P: FnOnce(Self) -> F,
116 F: futures::Future<Output = O>,
117 {
118let runtime = Self::create().expect("Failed to create runtime");
119 runtime.clone().block_on(func(runtime))
120 }
121}
122123#[cfg(feature = "rustls")]
124impl AsyncStdRustlsRuntime {
125/// Return a new [`AsyncStdRustlsRuntime`]
126 ///
127 /// Generally you should call this function only once, and then use
128 /// [`Clone::clone()`] to create additional references to that
129 /// runtime.
130pub fn create() -> IoResult<Self> {
131let rt = create_runtime_impl();
132let ct = RealCoarseTimeProvider::new();
133Ok(AsyncStdRustlsRuntime {
134 inner: CompoundRuntime::new(rt, rt, ct, rt, rt, RustlsProvider::default(), rt),
135 })
136 }
137138/// Return an [`AsyncStdRustlsRuntime`] for the currently running
139 /// `async_std` executor.
140 ///
141 /// Note that since async_std executors are global, there is no distinction
142 /// between this method and [`AsyncStdNativeTlsRuntime::create()`]: it is
143 /// provided only for API consistency with the Tokio runtimes.
144pub fn current() -> IoResult<Self> {
145Self::create()
146 }
147148/// Helper to run a single test function in a freshly created runtime.
149 ///
150 /// # Panics
151 ///
152 /// Panics if we can't create this runtime.
153 ///
154 /// # Warning
155 ///
156 /// This API is **NOT** for consumption outside Arti. Semver guarantees are not provided.
157#[doc(hidden)]
158pub fn run_test<P, F, O>(func: P) -> O
159where
160P: FnOnce(Self) -> F,
161 F: futures::Future<Output = O>,
162 {
163let runtime = Self::create().expect("Failed to create runtime");
164 runtime.clone().block_on(func(runtime))
165 }
166}
167168#[cfg(not(miri))] // async_ztd startup seems to fail under miri
169#[cfg(test)]
170mod test {
171// @@ begin test lint list maintained by maint/add_warning @@
172#![allow(clippy::bool_assert_comparison)]
173 #![allow(clippy::clone_on_copy)]
174 #![allow(clippy::dbg_macro)]
175 #![allow(clippy::mixed_attributes_style)]
176 #![allow(clippy::print_stderr)]
177 #![allow(clippy::print_stdout)]
178 #![allow(clippy::single_char_pattern)]
179 #![allow(clippy::unwrap_used)]
180 #![allow(clippy::unchecked_duration_subtraction)]
181 #![allow(clippy::useless_vec)]
182 #![allow(clippy::needless_pass_by_value)]
183//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
184use super::*;
185186#[test]
187fn current() {
188// We should actually have to run this inside a runtime with async_std,
189 // but let's do it anyway to make sure that "current" works.
190let runtime = PreferredRuntime::create().unwrap();
191 runtime.block_on(async {
192#[cfg(feature = "native-tls")]
193assert!(AsyncStdNativeTlsRuntime::current().is_ok());
194195#[cfg(feature = "rustls")]
196assert!(AsyncStdRustlsRuntime::current().is_ok());
197 });
198 }
199200#[test]
201fn debug() {
202#[cfg(feature = "native-tls")]
203assert_eq!(
204format!("{:?}", AsyncStdNativeTlsRuntime::create().unwrap()),
205"AsyncStdNativeTlsRuntime { .. }"
206);
207#[cfg(feature = "rustls")]
208assert_eq!(
209format!("{:?}", AsyncStdRustlsRuntime::create().unwrap()),
210"AsyncStdRustlsRuntime { .. }"
211);
212 }
213}