#[cfg(not(target_arch = "wasm32"))]
pub use native::*;
#[cfg(target_arch = "wasm32")]
pub use wasm::*;
#[cfg(not(target_arch = "wasm32"))]
mod native {
pub use tokio::spawn;
pub use tokio::task::spawn_blocking;
pub use tokio::time::{sleep, timeout};
pub trait SendSync: Send + Sync {}
impl<T: ?Sized + Send + Sync> SendSync for T {}
}
#[cfg(target_arch = "wasm32")]
mod wasm {
use futures::future::{select, Either};
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Duration;
#[derive(Debug)]
pub struct JoinError;
impl std::fmt::Display for JoinError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "wasm spawn_blocking error")
}
}
impl std::error::Error for JoinError {}
#[derive(Debug)]
pub struct Elapsed;
impl std::fmt::Display for Elapsed {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "deadline has elapsed")
}
}
impl std::error::Error for Elapsed {}
#[inline]
pub async fn sleep(duration: Duration) {
gloo_timers::future::sleep(duration).await;
}
#[inline]
pub async fn spawn_blocking<F, R>(f: F) -> Result<R, JoinError>
where
F: FnOnce() -> R + 'static,
R: 'static,
{
Ok(f())
}
pub async fn timeout<T>(duration: Duration, future: T) -> Result<T::Output, Elapsed>
where
T: Future,
{
let timer = Box::pin(sleep(duration));
let fut = Box::pin(future);
match select(fut, timer).await {
Either::Left((res, _)) => Ok(res),
Either::Right((_, _)) => Err(Elapsed),
}
}
pub struct JoinHandle {
_private: (),
}
impl Future for JoinHandle {
type Output = Result<(), JoinError>;
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(Ok(()))
}
}
pub fn spawn<F>(future: F) -> JoinHandle
where
F: Future<Output = ()> + 'static,
{
wasm_bindgen_futures::spawn_local(future);
JoinHandle { _private: () }
}
pub trait SendSync {}
impl<T: ?Sized> SendSync for T {}
}