twizzler_abi/syscall/time/
timedefs.rs1use core::{ops::Sub, time::Duration};
2
3use super::{FemtoSeconds, NanoSeconds, Seconds, FEMTOS_PER_NANO, FEMTOS_PER_SEC, NANOS_PER_SEC};
4
5#[derive(Clone, Copy, Debug, PartialEq)]
6pub struct TimeSpan(pub Seconds, pub FemtoSeconds);
7
8impl TimeSpan {
9 pub const ZERO: TimeSpan = TimeSpan(Seconds(0), FemtoSeconds(0));
10
11 pub const fn new(secs: u64, femtos: u64) -> TimeSpan {
12 TimeSpan(Seconds(secs), FemtoSeconds(femtos))
13 }
14
15 pub const fn from_secs(secs: u64) -> TimeSpan {
16 TimeSpan(Seconds(secs), FemtoSeconds(0))
17 }
18
19 pub const fn from_femtos(femtos: u64) -> TimeSpan {
20 TimeSpan(
21 Seconds(femtos / FEMTOS_PER_SEC),
22 FemtoSeconds(femtos % FEMTOS_PER_SEC),
23 )
24 }
25
26 pub const fn from_nanos(nanos: u64) -> TimeSpan {
27 TimeSpan(
28 Seconds(nanos / NANOS_PER_SEC),
29 FemtoSeconds((nanos % NANOS_PER_SEC) * FEMTOS_PER_NANO),
30 )
31 }
32
33 pub fn as_nanos(&self) -> u128 {
34 let nanos: NanoSeconds = self.1.into();
35 self.0 .0 as u128 * NANOS_PER_SEC as u128 + nanos.0 as u128
36 }
37
38 pub fn as_femtos(&self) -> u128 {
39 self.0 .0 as u128 * FEMTOS_PER_SEC as u128 + self.1 .0 as u128
40 }
41
42 pub const fn checked_sub(&self, other: TimeSpan) -> Option<TimeSpan> {
43 if self.0 .0 >= other.0 .0 {
44 let mut secs = self.0 .0 - other.0 .0;
45 let nanos = if self.1 .0 >= other.1 .0 {
46 self.1 .0 - other.1 .0
47 } else {
48 secs -= 1;
49 self.1 .0 + FEMTOS_PER_SEC - other.1 .0
50 };
51 return Some(TimeSpan(Seconds(secs), FemtoSeconds(nanos)));
52 }
53 None
55 }
56}
57
58impl From<TimeSpan> for Duration {
59 fn from(t: TimeSpan) -> Self {
60 let nanos: NanoSeconds = t.1.into();
61 Duration::new(t.0 .0, nanos.0 as u32)
62 }
63}
64
65impl Sub for TimeSpan {
66 type Output = Self;
67
68 fn sub(self, other: Self) -> Self::Output {
69 self.checked_sub(other)
70 .expect("overflow occured when subtracting TimeSpan")
71 }
72}