From 49bb084a4c166c1b565f8ab4951596426f0fda9b Mon Sep 17 00:00:00 2001 From: Pete Hayes Date: Fri, 12 Jun 2026 11:24:35 +1000 Subject: [PATCH 1/2] Add From conversion for Instant --- src/time/instant.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/time/instant.rs b/src/time/instant.rs index 0c041d4..10d08ba 100644 --- a/src/time/instant.rs +++ b/src/time/instant.rs @@ -123,6 +123,12 @@ impl Instant { } } +impl From for Instant { + fn from(duration: Duration) -> Self { + Self(duration) + } +} + impl Add for Instant { type Output = Self; From a9f56e9d3346d76361f7462fc67b059de3313671 Mon Sep 17 00:00:00 2001 From: Pete Hayes Date: Wed, 8 Jul 2026 11:40:32 +1000 Subject: [PATCH 2/2] Move patch to web.rs --- src/time/instant.rs | 8 +------- src/web.rs | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/time/instant.rs b/src/time/instant.rs index 10d08ba..08a07e6 100644 --- a/src/time/instant.rs +++ b/src/time/instant.rs @@ -21,7 +21,7 @@ use super::js::TIME_ORIGIN; doc = "[`std::time::Instant`]: https://doc.rust-lang.org/std/time/struct.Instant.html" )] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct Instant(Duration); +pub struct Instant(pub(crate) Duration); impl Instant { /// See [`std::time::Instant::now()`]. @@ -123,12 +123,6 @@ impl Instant { } } -impl From for Instant { - fn from(duration: Duration) -> Self { - Self(duration) - } -} - impl Add for Instant { type Output = Self; diff --git a/src/web.rs b/src/web.rs index d79d6a0..ce419f0 100644 --- a/src/web.rs +++ b/src/web.rs @@ -2,9 +2,10 @@ #![allow(clippy::absolute_paths)] +use core::time::Duration; use std::time::SystemTime as StdSystemTime; -use crate::SystemTime; +use crate::{Instant, SystemTime}; #[cfg(all( target_arch = "wasm32", @@ -79,3 +80,44 @@ impl SystemTimeExt for SystemTime { .expect("found `SystemTime` earlier than unix epoch") } } + +/// Web-specific extension to [`web_time::Instant`](crate::Instant). +pub trait InstantExt { + /// Create a [`web_time::Instant`](crate::Instant) from a [`Duration`] + /// representing the monotonic time elapsed since an arbitrary, fixed + /// origin. + /// + /// # Note + /// + /// The resulting [`Instant`](crate::Instant) is only meaningful relative to + /// other [`Instant`](crate::Instant)s that share the same origin (whether + /// obtained via [`Instant::now()`](crate::Instant::now) or this method). + /// Mixing timestamps from different origins will yield nonsensical + /// [`Duration`]s. + /// + /// [`Performance.now()`]: https://developer.mozilla.org/en-US/docs/Web/API/Performance/now + /// [`Performance.timeOrigin`]: https://developer.mozilla.org/en-US/docs/Web/API/Performance/timeOrigin + #[must_use] + fn from_duration(duration: Duration) -> Self; + + /// Returns the [`Duration`] backing this [`Instant`](crate::Instant), i.e. + /// the monotonic time elapsed since the origin it was created from. + /// + /// # Note + /// + /// Like [`InstantExt::from_duration`], the returned [`Duration`] is only + /// meaningful relative to other [`Instant`](crate::Instant)s sharing the + /// same origin. + #[must_use] + fn as_duration(&self) -> Duration; +} + +impl InstantExt for Instant { + fn from_duration(duration: Duration) -> Self { + Self(duration) + } + + fn as_duration(&self) -> Duration { + self.0 + } +}