Skip to main content

elph_agent/runtime/
mod.rs

1use std::future::Future;
2
3use anyhow::Result;
4
5fn run_future<F, T>(future: F) -> Result<T>
6where
7    F: Future<Output = T>,
8{
9    if let Ok(handle) = tokio::runtime::Handle::try_current() {
10        return Ok(tokio::task::block_in_place(|| handle.block_on(future)));
11    }
12
13    Ok(tokio::runtime::Builder::new_current_thread()
14        .enable_all()
15        .build()?
16        .block_on(future))
17}
18
19/// Runs an async future, panicking if the runtime cannot be created.
20pub fn block_on<F, T>(future: F) -> T
21where
22    F: Future<Output = T>,
23{
24    run_future(future).expect("failed to run async task")
25}
26
27/// Runs an async future, returning errors from runtime construction.
28pub fn try_block_on<F, T>(future: F) -> Result<T>
29where
30    F: Future<Output = T>,
31{
32    run_future(future)
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn try_block_on_works_outside_runtime() {
41        let value = try_block_on(async { 42 }).expect("outside runtime");
42        assert_eq!(value, 42);
43    }
44
45    #[tokio::test(flavor = "multi_thread")]
46    async fn try_block_on_works_inside_runtime() {
47        let value = try_block_on(async { 42 }).expect("inside runtime");
48        assert_eq!(value, 42);
49    }
50}