twizzler_abi/syscall/time/
timedefs.rs

1use 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, Default)]
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 fn from_femtos<P: Into<u128> + Copy>(femtos: P) -> TimeSpan {
20        TimeSpan(
21            Seconds((femtos.into() / FEMTOS_PER_SEC as u128) as u64),
22            FemtoSeconds((femtos.into() % FEMTOS_PER_SEC as u128) as u64),
23        )
24    }
25
26    pub fn from_nanos<P: Into<u128> + Copy>(nanos: P) -> TimeSpan {
27        TimeSpan(
28            Seconds((nanos.into() / NANOS_PER_SEC as u128) as u64),
29            FemtoSeconds(((nanos.into() % NANOS_PER_SEC as u128) * FEMTOS_PER_NANO as u128) as u64),
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        // rhs was bigger than lhs
54        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 From<Duration> for TimeSpan {
66    fn from(t: Duration) -> Self {
67        let nanos = t.as_nanos();
68        Self::from_nanos(nanos)
69    }
70}
71
72impl Sub for TimeSpan {
73    type Output = Self;
74
75    fn sub(self, other: Self) -> Self::Output {
76        self.checked_sub(other)
77            .expect("overflow occured when subtracting TimeSpan")
78    }
79}