use std::time::Duration;
pub fn format_duration(d: Duration) -> String {
let secs = d.as_secs();
let hours = secs / 3600;
let minutes = (secs % 3600) / 60;
let seconds = secs % 60;
if hours > 0 {
format!("{hours}h {minutes:02}m {seconds:02}s")
} else if minutes > 0 {
format!("{minutes}m {seconds:02}s")
} else {
format!("{seconds}s")
}
}
pub fn format_duration_precise(d: Duration) -> String {
let secs = d.as_secs();
format!(
"{:02}:{:02}:{:02}",
secs / 3600,
(secs % 3600) / 60,
secs % 60
)
}
pub fn format_duration_millis(d: Duration) -> String {
format!("{}.{:03}", format_duration_precise(d), d.subsec_millis())
}
pub fn format_eta(d: Duration) -> String {
format!("~{}", format_duration(d))
}
pub fn format_elapsed(d: Duration) -> String {
format_duration(d)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_zero_duration() {
assert_eq!(format_duration(Duration::ZERO), "0s");
}
#[test]
fn test_format_seconds() {
assert_eq!(format_duration(Duration::from_secs(42)), "42s");
}
#[test]
fn test_format_minutes_seconds() {
assert_eq!(format_duration(Duration::from_secs(194)), "3m 14s");
}
#[test]
fn test_format_hours_minutes_seconds() {
assert_eq!(format_duration(Duration::from_secs(4984)), "1h 23m 04s");
}
#[test]
fn test_format_precise_padding() {
assert_eq!(
format_duration_precise(Duration::from_secs(4984)),
"01:23:04"
);
}
#[test]
fn test_format_millis() {
assert_eq!(
format_duration_millis(Duration::from_millis(4_984_123)),
"01:23:04.123"
);
}
#[test]
fn test_format_eta_adds_tilde() {
assert_eq!(format_eta(Duration::from_secs(42)), "~42s");
}
#[test]
fn test_format_elapsed_no_tilde() {
assert_eq!(format_elapsed(Duration::from_secs(42)), "42s");
}
}