1use core::ops::{Add, AddAssign, Sub, SubAssign};
4use core::time::Duration;
5
6#[derive(Copy, Clone, Hash, Debug, Ord, PartialOrd, Eq, PartialEq)]
8pub struct Instant {
9 arch_val: u128
10}
11
12impl Instant {
13 fn nanos(&self) -> u128 {
14 Self::arch_to_nanos(self.arch_val)
15 }
16
17 fn arch_to_nanos(arch_val: u128) -> u128 {
18 let (num, denom) = crate::bridge::time::system_time_to_nanos();
19
20 arch_val * num / denom.get()
21 }
22
23 fn nanos_to_arch(nanos: u128) -> u128 {
24 let (num, denom) = crate::bridge::time::system_time_to_nanos();
25
26 nanos * denom.get() / num
27 }
28
29 pub fn now() -> Self {
31 let arch_val = crate::bridge::time::system_time();
32 Self {
33 arch_val
34 }
35 }
36
37 pub fn duration_since(&self, earlier: Instant) -> Duration {
38 self.saturating_duration_since(earlier)
39 }
40
41 pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
42 let nanos = self.nanos().checked_sub(earlier.nanos())?;
43 Some(Duration::new(
44 (nanos / 1_000_000_000) as u64,
45 (nanos % 1_000_000_000) as u32
46 ))
47 }
48
49 pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
50 let nanos = self.nanos().saturating_sub(earlier.nanos());
51 Duration::new(
52 (nanos / 1_000_000_000) as u64,
53 (nanos % 1_000_000_000) as u32
54 )
55 }
56
57 pub fn elapsed(&self) -> Duration {
59 Self::now() - *self
60 }
61
62 pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
63 let arch_val = self.arch_val.checked_add(Self::nanos_to_arch(duration.as_nanos()))?;
64 Some(Instant { arch_val })
65 }
66
67 pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
68 let arch_val = self.arch_val.checked_sub(Self::nanos_to_arch(duration.as_nanos()))?;
69 Some(Instant { arch_val })
70 }
71
72 pub fn nanos_since_boot(&self) -> u128 {
76 self.nanos()
77 }
78
79 pub fn get(&self) -> u128 { self.arch_val }
85}
86
87impl Add<Duration> for Instant {
88 type Output = Instant;
89
90 fn add(self, rhs: Duration) -> Self::Output {
91 Instant { arch_val: self.arch_val + Self::nanos_to_arch(rhs.as_nanos()) }
92 }
93}
94
95impl AddAssign<Duration> for Instant {
96 fn add_assign(&mut self, rhs: Duration) {
97 self.arch_val += Self::nanos_to_arch(rhs.as_nanos());
98 }
99}
100
101impl Sub for Instant {
102 type Output = Duration;
103
104 fn sub(self, rhs: Instant) -> Self::Output {
105 self.duration_since(rhs)
106 }
107}
108
109impl Sub<Duration> for Instant {
110 type Output = Instant;
111
112 fn sub(self, rhs: Duration) -> Self::Output {
113 Instant { arch_val: self.arch_val - Self::nanos_to_arch(rhs.as_nanos()) }
114 }
115}
116
117impl SubAssign<Duration> for Instant {
118 fn sub_assign(&mut self, rhs: Duration) {
119 self.arch_val -= Self::nanos_to_arch(rhs.as_nanos());
120 }
121}