#[derive(Debug, Eq, PartialEq)]
pub struct TimeParts {
pub hours: u32,
pub mins: u32,
pub secs: u64,
pub nanos: u64,
}
impl TimeParts {
pub fn from_nanos(total_nanos: u128) -> Self {
let whole_secs = u64::try_from(total_nanos / 1_000_000_000).unwrap();
let whole_mins = u32::try_from(whole_secs / 60).unwrap();
let whole_hours = whole_mins / 60;
let mins_part = whole_mins - whole_hours * 60;
let secs_part = whole_secs - u64::from(whole_mins) * 60;
let nanos_part =
u64::try_from(total_nanos - u128::from(whole_secs) * 1_000_000_000).unwrap();
Self {
hours: whole_hours,
mins: mins_part,
secs: secs_part,
nanos: nanos_part,
}
}
pub fn fmt_hr_min_sec(&self) -> TimePartsFmtHrMinSec {
TimePartsFmtHrMinSec { time: self }
}
pub fn fmt_hr_min_sec_milli(&self) -> TimePartsFmtHrMinSecMilli {
TimePartsFmtHrMinSecMilli { time: self }
}
pub fn fmt_hr_min_sec_nano(&self) -> TimePartsFmtHrMinSecNano {
TimePartsFmtHrMinSecNano { time: self }
}
}
pub struct TimePartsFmtHrMinSec<'a> {
time: &'a TimeParts,
}
impl std::fmt::Display for TimePartsFmtHrMinSec<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:02}:{:02}:{:02}",
self.time.hours, self.time.mins, self.time.secs
)
}
}
pub struct TimePartsFmtHrMinSecMilli<'a> {
time: &'a TimeParts,
}
impl std::fmt::Display for TimePartsFmtHrMinSecMilli<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:02}:{:02}:{:02}.{:03}",
self.time.hours,
self.time.mins,
self.time.secs,
self.time.nanos / 1_000_000
)
}
}
pub struct TimePartsFmtHrMinSecNano<'a> {
time: &'a TimeParts,
}
impl std::fmt::Display for TimePartsFmtHrMinSecNano<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:02}:{:02}:{:02}.{:09}",
self.time.hours, self.time.mins, self.time.secs, self.time.nanos,
)
}
}
#[cfg(test)]
#[test]
fn test_time_parts() {
use std::time::Duration;
assert_eq!(
TimeParts::from_nanos(
(Duration::from_nanos(1) + Duration::from_secs(3600 + 60 + 1)).as_nanos()
),
TimeParts {
hours: 1,
mins: 1,
secs: 1,
nanos: 1
}
);
}