pub fn format_bytes(n: u64) -> String {
const UNITS: &[&str] = &["B", "KiB", "MiB", "GiB", "TiB", "PiB"];
let mut value = n as f64;
let mut unit_idx = 0;
while value >= 1024.0 && unit_idx < UNITS.len() - 1 {
value /= 1024.0;
unit_idx += 1;
}
if unit_idx == 0 {
format!("{} {}", n, UNITS[0])
} else if value >= 100.0 {
format!("{:.0} {}", value, UNITS[unit_idx])
} else if value >= 10.0 {
format!("{:.1} {}", value, UNITS[unit_idx])
} else {
format!("{:.2} {}", value, UNITS[unit_idx])
}
}
pub fn format_secs(secs: u64) -> String {
if secs < 60 {
return format!("{}s", secs);
}
if secs < 3600 {
let m = secs / 60;
let s = secs % 60;
if s == 0 {
return format!("{}m", m);
}
return format!("{}m {}s", m, s);
}
if secs < 86_400 {
let h = secs / 3600;
let m = (secs % 3600) / 60;
if m == 0 {
return format!("{}h", h);
}
return format!("{}h {}m", h, m);
}
let d = secs / 86_400;
let h = (secs % 86_400) / 3600;
if h == 0 {
return format!("{}d", d);
}
format!("{}d {}h", d, h)
}
pub fn should_color() -> bool {
if std::env::var_os("NO_COLOR").is_some() {
return false;
}
if std::env::var_os("DRACON_FORCE_COLOR").is_some() {
return true;
}
use std::io::IsTerminal;
std::io::stdout().is_terminal()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_bytes_zero() {
assert_eq!(format_bytes(0), "0 B");
}
#[test]
fn format_bytes_under_kib() {
assert_eq!(format_bytes(512), "512 B");
assert_eq!(format_bytes(1023), "1023 B");
}
#[test]
fn format_bytes_kib() {
assert_eq!(format_bytes(1024), "1.00 KiB");
assert_eq!(format_bytes(15_728), "15.4 KiB");
}
#[test]
fn format_bytes_mib() {
assert_eq!(format_bytes(52_428_800), "50.0 MiB");
assert_eq!(format_bytes(1_572_864), "1.50 MiB");
}
#[test]
fn format_bytes_gib() {
assert_eq!(format_bytes(1_073_741_824), "1.00 GiB");
assert_eq!(format_bytes(4_831_838_208), "4.50 GiB");
}
#[test]
fn format_secs_units() {
assert_eq!(format_secs(0), "0s");
assert_eq!(format_secs(5), "5s");
assert_eq!(format_secs(59), "59s");
assert_eq!(format_secs(60), "1m");
assert_eq!(format_secs(130), "2m 10s");
assert_eq!(format_secs(3600), "1h");
assert_eq!(format_secs(3900), "1h 5m");
assert_eq!(format_secs(86_400), "1d");
assert_eq!(format_secs(90_000), "1d 1h");
}
#[test]
fn no_color_disables() {
let saved = std::env::var_os("NO_COLOR");
std::env::set_var("NO_COLOR", "1");
assert!(!should_color());
match saved {
Some(v) => std::env::set_var("NO_COLOR", v),
None => std::env::remove_var("NO_COLOR"),
}
}
}