use core::ops::{Add, Sub};
use core::time::Duration;
#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Instant(::std::time::Instant);
#[cfg(not(target_arch = "wasm32"))]
impl Add<Duration> for Instant {
type Output = Instant;
fn add(self, rhs: Duration) -> Instant {
Instant(self.0 + rhs)
}
}
#[cfg(not(target_arch = "wasm32"))]
impl Sub<Duration> for Instant {
type Output = Instant;
fn sub(self, rhs: Duration) -> Instant {
Instant(self.0 - rhs)
}
}
#[cfg(not(target_arch = "wasm32"))]
impl Instant {
#[must_use]
pub fn now() -> Self {
Instant(::std::time::Instant::now())
}
#[must_use]
pub fn elapsed(&self) -> Duration {
self.0.elapsed()
}
#[must_use]
pub fn duration_since(&self, earlier: Instant) -> Duration {
self.0.duration_since(earlier.0)
}
}
#[cfg(target_arch = "wasm32")]
use core::sync::atomic::{AtomicU64, Ordering};
#[cfg(target_arch = "wasm32")]
static TICKS: AtomicU64 = AtomicU64::new(0);
#[cfg(target_arch = "wasm32")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Instant(u64);
#[cfg(target_arch = "wasm32")]
impl Add<Duration> for Instant {
type Output = Instant;
fn add(self, rhs: Duration) -> Instant {
Instant(self.0.saturating_add(rhs.as_nanos() as u64))
}
}
#[cfg(target_arch = "wasm32")]
impl Sub<Duration> for Instant {
type Output = Instant;
fn sub(self, rhs: Duration) -> Instant {
Instant(self.0.saturating_sub(rhs.as_nanos() as u64))
}
}
#[cfg(target_arch = "wasm32")]
impl Instant {
#[must_use]
pub fn now() -> Self {
Instant(TICKS.fetch_add(1, Ordering::Relaxed))
}
#[must_use]
pub fn elapsed(&self) -> Duration {
Instant::now().duration_since(*self)
}
#[must_use]
pub fn duration_since(&self, earlier: Instant) -> Duration {
Duration::from_nanos(self.0.saturating_sub(earlier.0))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn now_is_monotonic_and_elapsed_is_nonnegative() {
let a = Instant::now();
let b = Instant::now();
let _d = b.duration_since(a);
let _e = a.elapsed();
}
}