1#![doc = include_str!("../README.md")]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![deny(
4 nonstandard_style,
5 rust_2018_idioms,
6 rustdoc::broken_intra_doc_links,
7 rustdoc::private_intra_doc_links
8)]
9#![forbid(non_ascii_idents, unsafe_code)]
10#![warn(
11 deprecated_in_future,
12 missing_copy_implementations,
13 missing_debug_implementations,
14 missing_docs,
15 unreachable_pub,
16 unused_import_braces,
17 unused_labels,
18 unused_lifetimes,
19 unused_qualifications,
20 unused_results
21)]
22#![allow(clippy::uninlined_format_args)]
23
24use std::{any::Any, fmt, future::Future, time::Duration};
25
26#[derive(Clone, Copy, Debug, Eq, PartialEq)]
28pub enum Runtime {
29 #[cfg(feature = "tokio_1")]
30 #[cfg_attr(docsrs, doc(cfg(feature = "tokio_1")))]
31 Tokio1,
33
34 #[cfg(feature = "async-std_1")]
35 #[cfg_attr(docsrs, doc(cfg(feature = "async-std_1")))]
36 AsyncStd1,
38}
39
40impl Runtime {
41 #[allow(unused_variables)]
48 pub async fn timeout<F>(&self, duration: Duration, future: F) -> Option<F::Output>
49 where
50 F: Future,
51 {
52 match self {
53 #[cfg(feature = "tokio_1")]
54 Self::Tokio1 => tokio_1::time::timeout(duration, future).await.ok(),
55 #[cfg(feature = "async-std_1")]
56 Self::AsyncStd1 => async_std_1::future::timeout(duration, future).await.ok(),
57 #[allow(unreachable_patterns)]
58 _ => unreachable!(),
59 }
60 }
61
62 #[allow(unused_variables)]
68 pub async fn spawn_blocking<F, R>(&self, f: F) -> Result<R, SpawnBlockingError>
69 where
70 F: FnOnce() -> R + Send + 'static,
71 R: Send + 'static,
72 {
73 match self {
74 #[cfg(feature = "tokio_1")]
75 Self::Tokio1 => tokio_1::task::spawn_blocking(f)
76 .await
77 .map_err(|e| SpawnBlockingError::Panic(e.into_panic())),
78 #[cfg(feature = "async-std_1")]
79 Self::AsyncStd1 => Ok(async_std_1::task::spawn_blocking(f).await),
80 #[allow(unreachable_patterns)]
81 _ => unreachable!(),
82 }
83 }
84
85 #[allow(unused_variables)]
94 pub fn spawn_blocking_background<F>(&self, f: F) -> Result<(), SpawnBlockingError>
95 where
96 F: FnOnce() + Send + 'static,
97 {
98 match self {
99 #[cfg(feature = "tokio_1")]
100 Self::Tokio1 => {
101 drop(tokio_1::task::spawn_blocking(f));
102 Ok(())
103 }
104 #[cfg(feature = "async-std_1")]
105 Self::AsyncStd1 => {
106 drop(async_std_1::task::spawn_blocking(f));
107 Ok(())
108 }
109 #[allow(unreachable_patterns)]
110 _ => unreachable!(),
111 }
112 }
113}
114
115#[derive(Debug)]
117pub enum SpawnBlockingError {
118 Panic(Box<dyn Any + Send + 'static>),
120}
121
122impl fmt::Display for SpawnBlockingError {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 match self {
125 Self::Panic(p) => write!(f, "SpawnBlockingError: Panic: {:?}", p),
126 }
127 }
128}
129
130impl std::error::Error for SpawnBlockingError {}