ctrlc_async/
helper.rs

1//! Helper routines for the asynchronous functions
2
3use std::future::Future;
4use std::time::Duration;
5
6/// Spawns a background thread using which ever asynchronous runtime the library is built with
7pub fn spawn<T>(future: T)
8where T: Future + Send + 'static, T::Output: Send + 'static,
9{
10    #[cfg(feature = "tokio")]
11    if tokio::runtime::Handle::try_current().is_ok() {
12        tokio::spawn(future);
13    } else {
14        std::thread::Builder::new()
15            .spawn(move || {
16                let rt = tokio::runtime::Builder::new_current_thread()
17                    .enable_all()
18                    .build()
19                    .unwrap();
20                rt.block_on(future);
21            })
22            .expect("failed to spawn thread");
23    }
24
25    #[cfg(feature = "async-std")]
26    std::thread::Builder::new()
27        .spawn(move || {
28            async_std::task::block_on(future);
29        })
30        .expect("failed to spawn thread");
31}
32
33/// Safely executing blocking code using which ever asynchronous runtime the library is built with
34pub fn block_on<F>(mut task: F)
35where F: FnMut() -> () + 'static + Send,
36{
37    #[cfg(feature = "tokio")]
38    if tokio::runtime::Handle::try_current().is_ok() {
39        tokio::task::spawn_blocking(move || {
40            task();
41        });
42        return;
43    }
44
45    #[cfg(feature = "async-std")]
46    if async_std::task::try_current().is_some() {
47        std::thread::Builder::new()
48            .spawn(task)
49            .expect("failed to spawn thread");
50        return;
51    }
52
53    task();
54}
55
56/// Executes a future with a specific timeout using which ever asynchronous runtime the library is built with
57#[must_use = "this `Option` should be handled"]
58pub async fn timeout<F>(duration: Duration, future: F) -> Option<F::Output>
59where F: Future
60{
61    #[cfg(feature = "tokio")]
62    return match tokio::time::timeout(duration, future).await {
63        Ok(a) => Some(a),
64        Err(_) => None
65    };
66
67    #[cfg(feature = "async-std")]
68    return match async_std::future::timeout(duration, future).await {
69        Ok(a) => Some(a),
70        Err(_) => None
71    };
72}