cross-runtime 0.1.0

One task, timer, and runtime surface across native Tokio and browser WebAssembly
Documentation
use std::future::Future;

#[cfg(not(target_arch = "wasm32"))]
use std::sync::Arc;

/// An owned task runtime on native targets and the ambient browser runtime on WebAssembly.
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone)]
pub struct Runtime(Arc<tokio::runtime::Runtime>);

#[cfg(not(target_arch = "wasm32"))]
impl Default for Runtime {
    fn default() -> Self {
        let mut builder = tokio::runtime::Builder::new_multi_thread();
        builder.enable_all();
        Self(Arc::new(builder.build().unwrap_or_else(|error| {
            panic!("failed to create Tokio runtime: {error}")
        })))
    }
}

#[cfg(not(target_arch = "wasm32"))]
impl Runtime {
    /// Use an existing Tokio runtime as this runtime's native executor.
    pub fn from_tokio(runtime: Arc<tokio::runtime::Runtime>) -> Self {
        Self(runtime)
    }

    /// Access the native Tokio runtime.
    pub fn tokio(&self) -> &tokio::runtime::Runtime {
        &self.0
    }

    /// Clone the shared native Tokio runtime.
    pub fn tokio_arc(&self) -> Arc<tokio::runtime::Runtime> {
        self.0.clone()
    }

    /// Run a future to completion on the native runtime.
    pub fn block_on<F: Future>(&self, future: F) -> F::Output {
        self.0.block_on(future)
    }

    /// Spawn a `Send` task on the native runtime.
    pub fn spawn<F>(&self, future: F) -> crate::JoinHandle<F::Output>
    where
        F: Future + Send + 'static,
        F::Output: Send + 'static,
    {
        self.0.spawn(future)
    }
}

/// The ambient browser task runtime.
#[cfg(target_arch = "wasm32")]
#[derive(Clone, Copy, Debug, Default)]
pub struct Runtime;

#[cfg(target_arch = "wasm32")]
impl Runtime {
    /// Spawn a `Send` task which may follow its waker across browser workers.
    pub fn spawn<F>(&self, future: F) -> crate::JoinHandle<F::Output>
    where
        F: Future + Send + 'static,
        F::Output: Send + 'static,
    {
        crate::spawn(future)
    }
}