use std::time::Duration;
const BPS_UNITS: [&str; 5] = ["bps", "Kbps", "Mbps", "Gbps", "Tbps"];
const BYTE_UNITS: [&str; 5] = ["B", "KB", "MB", "GB", "TB"];
const STEP: f64 = 1000.0;
#[must_use]
pub fn format_bps(bps: f64) -> String {
let (value, unit) = scale(bps.max(0.0), &BPS_UNITS);
format!("{value:.1} {unit}")
}
#[must_use]
pub fn split_bps(bps: f64) -> (String, &'static str) {
let (value, unit) = scale(bps.max(0.0), &BPS_UNITS);
(format!("{value:.1}"), unit)
}
#[must_use]
pub fn format_bytes(bytes: u64) -> String {
let (value, unit) = scale(bytes as f64, &BYTE_UNITS);
if unit == "B" {
format!("{bytes} B")
} else {
format!("{value:.2} {unit}")
}
}
#[must_use]
pub fn format_duration(duration: Duration) -> String {
let total = duration.as_secs();
format!("{:02}:{:02}", total / 60, total % 60)
}
#[must_use]
pub fn format_eta(duration: Duration) -> String {
let total = duration.as_secs();
if total >= 60 {
format!("{}m {:02}s", total / 60, total % 60)
} else {
format!("{total}s")
}
}
#[must_use]
pub fn format_millis(ms: f64) -> String {
if ms >= 100.0 {
format!("{ms:.0} ms")
} else {
format!("{ms:.1} ms")
}
}
fn scale(value: f64, units: &[&'static str; 5]) -> (f64, &'static str) {
let mut scaled = value;
let mut index = 0;
while scaled >= STEP && index < units.len() - 1 {
scaled /= STEP;
index += 1;
}
(scaled, units[index])
}