diff --git a/src/lib.rs b/src/lib.rs index 077c9d4..bd06797 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,11 +11,13 @@ cfg_if::cfg_if! { pub use wasm::Instant; #[cfg(feature = "now")] pub use crate::wasm::now; + pub use wasm::SystemTime; } else { mod native; pub use native::Instant; #[cfg(feature = "now")] pub use native::now; + pub use native::SystemTime; } } diff --git a/src/native.rs b/src/native.rs index 37d5da4..7deefb6 100644 --- a/src/native.rs +++ b/src/native.rs @@ -1,4 +1,5 @@ pub type Instant = std::time::Instant; +pub type SystemTime = std::time::SystemTime; /// The current time, in milliseconds. #[cfg(feature = "now")] diff --git a/src/wasm.rs b/src/wasm.rs index 7914fb5..3e416b4 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::ops::{Add, AddAssign, Sub, SubAssign}; use std::time::Duration; @@ -160,3 +161,80 @@ pub fn now() -> f64 { #[cfg(target_os = "emscripten")] return unsafe { js::_emscripten_get_now() }; } + +/// Returns the number of millisecods elapsed since January 1, 1970 00:00:00 UTC. +#[cfg(any(feature = "wasm-bindgen", feature = "stdweb"))] +fn get_time() -> f64 { + #[cfg(feature = "wasm-bindgen")] + return js_sys::Date::now(); + #[cfg(all(feature = "stdweb", not(feature = "wasm-bindgen")))] + { + let v = js! { return Date.now(); }; + return v.try_into().unwrap(); + } +} + +#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] +pub struct SystemTime(f64); + +impl SystemTime { + pub const UNIX_EPOCH: SystemTime = SystemTime(0.0); + + pub fn now() -> SystemTime { + cfg_if::cfg_if! { + if #[cfg(any(feature = "wasm-bindgen", feature = "stdweb"))] { + SystemTime(get_time()) + } else { + SystemTime(now()) + } + } + } + + pub fn duration_since(&self, earlier: SystemTime) -> Result { + let dur_ms = self.0 - earlier.0; + 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 { + SystemTime(self.0 + other.as_millis() as f64) + } +} + +impl Sub for SystemTime { + type Output = SystemTime; + + fn sub(self, other: Duration) -> SystemTime { + SystemTime(self.0 - other.as_millis() 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; + } +} diff --git a/tests/wasm.rs b/tests/wasm.rs index 863eefd..e858faa 100644 --- a/tests/wasm.rs +++ b/tests/wasm.rs @@ -1,6 +1,6 @@ extern crate wasm_bindgen_test; -use instant::Instant; +use instant::{Instant, SystemTime}; use std::time::Duration; use wasm_bindgen_test::*; @@ -47,3 +47,11 @@ fn test_checked_sub() { .checked_sub(Duration::new(u64::MAX, ONE_BILLION - 1)) .is_none()); } + +#[wasm_bindgen_test] +fn test_system_time() { + assert!(SystemTime::UNIX_EPOCH + .duration_since(SystemTime::now()) + .is_err()); +} +