shadow_shim_helper_rs/util/
time.rs

1/// Helper for formatting times.
2#[derive(Debug, Eq, PartialEq)]
3pub struct TimeParts {
4    pub hours: u32,
5    pub mins: u32,
6    pub secs: u64,
7    pub nanos: u64,
8}
9
10impl TimeParts {
11    pub fn from_nanos(total_nanos: u128) -> Self {
12        // Total number of integer seconds.
13        let whole_secs = u64::try_from(total_nanos / 1_000_000_000).unwrap();
14        // Total number of integer minutes.
15        let whole_mins = u32::try_from(whole_secs / 60).unwrap();
16        // Total number of integer hours, which is also the hours part.
17        let whole_hours = whole_mins / 60;
18
19        // Integer minutes, after whole hours are subtracted out.
20        let mins_part = whole_mins - whole_hours * 60;
21        // Integers secs, after integer minutes are subtracted out.
22        let secs_part = whole_secs - u64::from(whole_mins) * 60;
23        // Nanos, after integer secs are subtracted out.
24        let nanos_part =
25            u64::try_from(total_nanos - u128::from(whole_secs) * 1_000_000_000).unwrap();
26
27        Self {
28            hours: whole_hours,
29            mins: mins_part,
30            secs: secs_part,
31            nanos: nanos_part,
32        }
33    }
34
35    /// Format as HH:MM:SS.
36    pub fn fmt_hr_min_sec(&self) -> TimePartsFmtHrMinSec {
37        TimePartsFmtHrMinSec { time: self }
38    }
39
40    /// Format as HH:MM:SS.mmm.
41    pub fn fmt_hr_min_sec_milli(&self) -> TimePartsFmtHrMinSecMilli {
42        TimePartsFmtHrMinSecMilli { time: self }
43    }
44
45    /// Format as HH:MM:SS.nnnnnnnnn.
46    pub fn fmt_hr_min_sec_nano(&self) -> TimePartsFmtHrMinSecNano {
47        TimePartsFmtHrMinSecNano { time: self }
48    }
49}
50
51pub struct TimePartsFmtHrMinSec<'a> {
52    time: &'a TimeParts,
53}
54
55impl std::fmt::Display for TimePartsFmtHrMinSec<'_> {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        write!(
58            f,
59            "{:02}:{:02}:{:02}",
60            self.time.hours, self.time.mins, self.time.secs
61        )
62    }
63}
64
65pub struct TimePartsFmtHrMinSecMilli<'a> {
66    time: &'a TimeParts,
67}
68
69impl std::fmt::Display for TimePartsFmtHrMinSecMilli<'_> {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        write!(
72            f,
73            "{:02}:{:02}:{:02}.{:03}",
74            self.time.hours,
75            self.time.mins,
76            self.time.secs,
77            self.time.nanos / 1_000_000
78        )
79    }
80}
81
82pub struct TimePartsFmtHrMinSecNano<'a> {
83    time: &'a TimeParts,
84}
85
86impl std::fmt::Display for TimePartsFmtHrMinSecNano<'_> {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        write!(
89            f,
90            "{:02}:{:02}:{:02}.{:09}",
91            self.time.hours, self.time.mins, self.time.secs, self.time.nanos,
92        )
93    }
94}
95
96#[cfg(test)]
97#[test]
98fn test_time_parts() {
99    use std::time::Duration;
100    assert_eq!(
101        TimeParts::from_nanos(
102            (Duration::from_nanos(1) + Duration::from_secs(3600 + 60 + 1)).as_nanos()
103        ),
104        TimeParts {
105            hours: 1,
106            mins: 1,
107            secs: 1,
108            nanos: 1
109        }
110    );
111}