re_viewer_context/
async_runtime_handle.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#[cfg(not(target_arch = "wasm32"))]
pub trait WasmNotSend: Send {}

#[cfg(target_arch = "wasm32")]
pub trait WasmNotSend {}

#[cfg(not(target_arch = "wasm32"))]
impl<T: Send> WasmNotSend for T {}

#[cfg(target_arch = "wasm32")]
impl<T> WasmNotSend for T {}

#[derive(Debug, thiserror::Error)]
pub enum AsyncRuntimeError {
    /// Tokio returned an error.
    ///
    /// We cannot leak a tokio type, so we have to convert it to a string.
    #[error("Tokio error: {0}")]
    TokioError(String),
}

/// Thin abstraction over the async runtime.
///
/// This allows us to use tokio on native and the browser futures.
#[derive(Clone)]
pub struct AsyncRuntimeHandle {
    #[cfg(not(target_arch = "wasm32"))]
    tokio: tokio::runtime::Handle,
}

impl AsyncRuntimeHandle {
    #[cfg(not(target_arch = "wasm32"))]
    pub fn new_native(tokio: tokio::runtime::Handle) -> Self {
        Self { tokio }
    }

    #[cfg(target_arch = "wasm32")]
    pub fn new_web() -> Self {
        Self {}
    }

    /// Create an `AsyncRuntime` from the current tokio runtime on native.
    #[cfg_attr(target_arch = "wasm32", expect(clippy::unnecessary_wraps))]
    pub fn from_current_tokio_runtime_or_wasmbindgen() -> Result<Self, AsyncRuntimeError> {
        #[cfg(target_arch = "wasm32")]
        {
            Ok(Self::new_web())
        }
        #[cfg(not(target_arch = "wasm32"))]
        {
            Ok(Self::new_native(
                tokio::runtime::Handle::try_current()
                    .map_err(|err| AsyncRuntimeError::TokioError(err.to_string()))?
                    .clone(),
            ))
        }
    }

    #[cfg(target_arch = "wasm32")]
    #[expect(clippy::unused_self)]
    pub fn spawn_future<F>(&self, future: F)
    where
        F: std::future::Future<Output = ()> + WasmNotSend + 'static,
    {
        wasm_bindgen_futures::spawn_local(future);
    }

    #[cfg(not(target_arch = "wasm32"))]
    pub fn spawn_future<F>(&self, future: F)
    where
        F: std::future::Future<Output = ()> + WasmNotSend + 'static,
    {
        self.tokio.spawn(future);
    }
}