use crate::{BoxFuture, Clock, Timer};
use jiff::Timestamp;
use jiff::tz::TimeZone;
use std::time::Duration;
#[derive(Debug)]
pub struct WasmClock;
impl Clock for WasmClock {
fn now(&self) -> Timestamp {
let ms = js_sys::Date::now(); Timestamp::from_millisecond(ms as i64).unwrap_or(Timestamp::UNIX_EPOCH)
}
}
pub fn browser_local_tz() -> TimeZone {
use js_sys::{Array, Intl, Object, Reflect};
use wasm_bindgen::JsValue;
let fmt = Intl::DateTimeFormat::new(&Array::new(), &Object::new());
let resolved = fmt.resolved_options();
Reflect::get(&resolved, &JsValue::from_str("timeZone"))
.ok()
.and_then(|v| v.as_string())
.and_then(|s| TimeZone::get(&s).ok())
.unwrap_or(TimeZone::UTC)
}
#[derive(Debug)]
pub struct WasmTimer;
impl Timer for WasmTimer {
fn sleep(&self, dur: Duration) -> BoxFuture<'static, ()> {
let ms = dur.as_millis().min(i32::MAX as u128) as i32;
let promise = js_sys::Promise::new(&mut |resolve, _reject| {
if let Some(win) = web_sys::window() {
let _ = win.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, ms);
}
});
Box::pin(async move {
let _ = wasm_bindgen_futures::JsFuture::from(promise).await;
})
}
fn next_tick(&self) -> BoxFuture<'static, ()> {
self.sleep(Duration::ZERO)
}
}