1use core::{ops::Sub, time::Duration};
2
3pub trait InstantProvider<D = Duration>
8where
9 Self: Sub<Self, Output = D> + Clone,
11{
12 fn now() -> Self;
14
15 fn elapsed(&self) -> D {
17 Self::now() - self.clone()
18 }
19}
20
21#[cfg(feature = "std")]
22impl InstantProvider<std::time::Duration> for std::time::Instant {
23 fn now() -> Self {
24 std::time::Instant::now()
25 }
26}
27
28#[cfg(feature = "embassy")]
29impl InstantProvider<embassy_time::Duration> for embassy_time::Instant {
30 fn now() -> Self {
31 embassy_time::Instant::now()
32 }
33}
34
35#[cfg(feature = "wasm")]
36pub mod wasm {
37 use core::{ops::Sub, time::Duration};
41
42 use crate::InstantProvider;
43
44 #[derive(Clone, PartialEq)]
48 pub struct Instant(f64);
49
50 impl Sub for Instant {
51 type Output = Duration;
52
53 fn sub(self, rhs: Self) -> Self::Output {
54 let delta_ms = self.0 - rhs.0;
56 let millis = delta_ms.trunc() as u64;
57 let micros = (delta_ms.fract() * 1000.0) as u64;
58 Duration::from_millis(millis) + Duration::from_micros(micros)
59 }
60 }
61
62 impl InstantProvider<Duration> for Instant {
63 fn now() -> Self {
64 Instant(js_sys::Date::now())
65 }
66 }
67}