diff --git a/src/time/mod.rs b/src/time/mod.rs index ff99832..a309900 100644 --- a/src/time/mod.rs +++ b/src/time/mod.rs @@ -13,7 +13,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use wasip2::clocks::{ monotonic_clock::{subscribe_duration, subscribe_instant}, - wall_clock, + wall_clock::{self, Datetime}, }; use crate::{ @@ -28,11 +28,30 @@ use crate::{ pub struct SystemTime(wall_clock::Datetime); impl SystemTime { + pub const UNIX_EPOCH: SystemTime = SystemTime(Datetime { + seconds: 0, + nanoseconds: 0, + }); + pub fn now() -> Self { Self(wall_clock::now()) } + + pub fn duration_since(&self, earlier: SystemTime) -> Result { + if self.0.seconds >= earlier.0.seconds && self.0.nanoseconds >= earlier.0.nanoseconds { + return Ok(Duration::new( + self.0.seconds - earlier.0.seconds, + self.0.nanoseconds - earlier.0.nanoseconds, + )); + } + + Err(SystemTimeError) + } } +#[derive(Debug, Clone, Copy)] +pub struct SystemTimeError; + /// An async iterator representing notifications at fixed interval. pub fn interval(duration: Duration) -> Interval { Interval { duration } @@ -113,6 +132,18 @@ mod test { println!("{what} awaited for {} s", d.as_secs_f32()); } + #[test] + fn systemtime_duration_since() { + crate::runtime::block_on(async { + let earlier = SystemTime::UNIX_EPOCH; + let now = SystemTime::now(); + + assert!(now.duration_since(earlier).is_ok()); + assert!(now.duration_since(now).is_ok_and(|x| x.as_secs() == 0)); + assert!(earlier.duration_since(now).is_err()); + }); + } + #[test] fn timer_now() { crate::runtime::block_on(debug_duration("timer_now", async {