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)]
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        // 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 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}