diff --git a/Cargo.toml b/Cargo.toml index 0d6392c..822ab23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,13 +2,14 @@ name = "wasm-timer" edition = "2018" description = "Abstraction over std::time::Instant and tokio_timer that works on WASM" -version = "0.1.1" +version = "0.1.2" authors = ["Pierre Krieger "] license = "MIT" repository = "https://github.com/tomaka/wasm-timer" [target.'cfg(any(target_arch = "wasm32"))'.dependencies] futures = "0.1" +js-sys = "0.3.14" send_wrapper = "0.2" wasm-bindgen = "0.2.37" web-sys = { version = "0.3.14", features = ["Performance", "Window"] } diff --git a/src/lib.rs b/src/lib.rs index 312f518..31aee1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ // DEALINGS IN THE SOFTWARE. #[cfg(not(target_arch = "wasm32"))] -pub use std::time::Instant; +pub use std::time::{Instant, SystemTime, UNIX_EPOCH}; #[cfg(not(target_arch = "wasm32"))] pub use tokio_timer::*; #[cfg(target_arch = "wasm32")] diff --git a/src/wasm.rs b/src/wasm.rs index 7747454..41c9404 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -24,7 +24,7 @@ use futures::{prelude::*, sync::oneshot, try_ready}; use std::{error, fmt}; use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering}; -use std::ops::{Add, Sub}; +use std::ops::{Add, Sub, AddAssign, SubAssign}; use std::time::Duration; use wasm_bindgen::{prelude::*, JsCast}; @@ -105,6 +105,95 @@ impl Sub for Instant { } } +pub const UNIX_EPOCH: SystemTime = SystemTime { inner: 0.0 }; + +#[derive(Debug, Copy, Clone)] +pub struct SystemTime { + /// Unit is milliseconds. + inner: f64, +} + +impl PartialEq for SystemTime { + fn eq(&self, other: &SystemTime) -> bool { + // Note that this will most likely only compare equal if we clone an `SystemTime`, + // but that's ok. + self.inner == other.inner + } +} + +impl Eq for SystemTime {} + +impl PartialOrd for SystemTime { + fn partial_cmp(&self, other: &SystemTime) -> Option { + self.inner.partial_cmp(&other.inner) + } +} + +impl Ord for SystemTime { + fn cmp(&self, other: &Self) -> Ordering { + self.inner.partial_cmp(&other.inner).unwrap() + } +} + +impl SystemTime { + pub const UNIX_EPOCH: SystemTime = SystemTime { inner: 0.0 }; + + pub fn now() -> SystemTime { + let val = js_sys::Date::now(); + SystemTime { inner: val } + } + + pub fn duration_since(&self, earlier: SystemTime) -> Result { + let dur_ms = self.inner - earlier.inner; + if dur_ms < 0.0 { + return Err(()) + } + Ok(Duration::from_millis(dur_ms as u64)) + } + + pub fn elapsed(&self) -> Result { + self.duration_since(SystemTime::now()) + } + + pub fn checked_add(&self, duration: Duration) -> Option { + Some(*self + duration) + } + + pub fn checked_sub(&self, duration: Duration) -> Option { + Some(*self - duration) + } +} + +impl Add for SystemTime { + type Output = SystemTime; + + fn add(self, other: Duration) -> SystemTime { + let new_val = self.inner + other.as_millis() as f64; + SystemTime { inner: new_val as f64 } + } +} + +impl Sub for SystemTime { + type Output = SystemTime; + + fn sub(self, other: Duration) -> SystemTime { + let new_val = self.inner - other.as_millis() as f64; + SystemTime { inner: new_val as f64 } + } +} + +impl AddAssign for SystemTime { + fn add_assign(&mut self, rhs: Duration) { + *self = *self + rhs; + } +} + +impl SubAssign for SystemTime { + fn sub_assign(&mut self, rhs: Duration) { + *self = *self - rhs; + } +} + #[derive(Debug)] pub struct Error;