pub fn format_duration_millis(millis: i64) -> String {
format_duration_millis_i128(i128::from(millis))
}
fn format_tenths(value_tenths: i128, unit: &str) -> String {
let whole = value_tenths / 10;
let tenths = value_tenths % 10;
if tenths > 0 {
format!("{}.{}{}", whole, tenths, unit)
} else {
format!("{}{}", whole, unit)
}
}
fn div_round_half_up(value: i128, divisor: i128) -> i128 {
let quotient = value / divisor;
let remainder = value % divisor;
if remainder >= divisor - remainder {
quotient.saturating_add(1)
} else {
quotient
}
}
fn format_duration_seconds(total_seconds: i128) -> String {
let hours = total_seconds / 3600;
let minutes = (total_seconds % 3600) / 60;
let seconds = total_seconds % 60;
if hours > 0 {
if minutes > 0 && seconds > 0 {
format!("{}h {}m {}s", hours, minutes, seconds)
} else if minutes > 0 {
format!("{}h {}m", hours, minutes)
} else if seconds > 0 {
format!("{}h {}s", hours, seconds)
} else {
format!("{}h", hours)
}
} else if minutes > 0 {
if seconds > 0 {
format!("{}m {}s", minutes, seconds)
} else {
format!("{}m", minutes)
}
} else {
format!("{}s", seconds)
}
}
fn format_duration_millis_i128(millis: i128) -> String {
if millis < 0 {
return "0 ms".to_string();
}
if millis < 1000 {
return format!("{} ms", millis);
}
if millis < 60_000 {
let tenths = div_round_half_up(millis, 100);
if tenths >= 600 {
return format_duration_seconds(tenths / 10);
}
return format_tenths(tenths, "s");
}
format_duration_seconds(div_round_half_up(millis, 1000))
}
pub fn format_duration_nanos(nanos: i128) -> String {
if nanos < 0 {
return "0 ns".to_string();
}
if nanos < 1000 {
return format!("{} ns", nanos);
}
if nanos < 1_000_000 {
let tenths = div_round_half_up(nanos, 100);
if tenths >= 10_000 {
return format_duration_nanos(tenths * 100);
}
format_tenths(tenths, " μs")
} else if nanos < 1_000_000_000 {
let tenths = div_round_half_up(nanos, 100_000);
if tenths >= 10_000 {
return format_duration_nanos(tenths * 100_000);
}
format_tenths(tenths, " ms")
} else if nanos < 60_000_000_000 {
let tenths = div_round_half_up(nanos, 100_000_000);
if tenths >= 600 {
return format_duration_seconds(tenths / 10);
}
format_tenths(tenths, "s")
} else {
format_duration_seconds(div_round_half_up(nanos, 1_000_000_000))
}
}
pub fn format_speed(speed: f64, unit: &str) -> String {
if speed.is_nan() || speed.is_infinite() {
"N/A".to_string()
} else {
format!("{:.2}{}", speed, unit)
}
}