use std::fmt;
use std::future::Future;
use std::time::Duration;
pub async fn sleep(duration: Duration) {
wasm_bindgen_futures::JsFuture::from(js_sys::Promise::new(&mut |resolve, _| {
let global = js_sys::global();
let set_timeout: js_sys::Function = js_sys::Reflect::get(&global, &"setTimeout".into())
.unwrap()
.into();
let _ = set_timeout.call2(
&wasm_bindgen::JsValue::NULL,
&resolve,
&wasm_bindgen::JsValue::from_f64(duration.as_millis() as f64),
);
}))
.await
.unwrap();
}
#[derive(Debug)]
pub struct Elapsed;
impl fmt::Display for Elapsed {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "deadline has elapsed")
}
}
impl std::error::Error for Elapsed {}
pub async fn timeout<F: Future>(duration: Duration, future: F) -> Result<F::Output, Elapsed> {
tokio::select! {
result = future => Ok(result),
_ = sleep(duration) => Err(Elapsed),
}
}