refactor(cli): unify scalar presentation formatting
Stream output, the run summary, and the TUI each carried their own copy of the same scalar vocabulary, and they had drifted: the TUI spelled microseconds "us" while the others used "µs", percentages guarded non-finite values in one place but not another, and the absent-value placeholder was spelled inline everywhere. cmd::format now owns nanosecond-scalar, percentage, and count formatting with one documented unit-selection and rounding policy, µs everywhere, and signed values preserved. The frontends keep their own metric sets and layouts; the TUI keeps its coarse wall-clock span policy, now named format_span and documented as deliberately distinct, and uses the shared scalar vocabulary below one second.
This commit is contained in:
1 parent
90c04b6569
commit
69b90dd64a
5 files changed
+257
-148
No files matched your search
@@ -10,6 +10,7 @@ use irtt_client::{
|
||||
};
|
||||
|
||||
use super::args::{HeaderMode, OutputFormat};
|
||||
use crate::cmd::format::{format_duration, format_signed_duration, ABSENT};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct OutputConfig {
|
||||
@@ -817,7 +818,7 @@ fn render_table_row(row: &OutputRow, columns: &[Column], context: RenderContext<
|
||||
}
|
||||
|
||||
fn format_table_cell(column: &Column, value: Option<String>) -> String {
|
||||
let value = value.unwrap_or_else(|| "-".to_owned());
|
||||
let value = value.unwrap_or_else(|| ABSENT.to_owned());
|
||||
let width = column.table_width();
|
||||
if column.align_right() {
|
||||
format!("{value:>width$}")
|
||||
@@ -1161,34 +1162,6 @@ fn wall_time_ns(wall: SystemTime) -> Option<u128> {
|
||||
.map(|duration| duration.as_nanos())
|
||||
}
|
||||
|
||||
fn format_duration(duration: Duration) -> String {
|
||||
format_ns(duration.as_nanos() as f64)
|
||||
}
|
||||
|
||||
fn format_signed_duration(duration: SignedDuration) -> String {
|
||||
format_signed_ns(duration.as_nanos() as f64)
|
||||
}
|
||||
|
||||
fn format_signed_ns(ns: f64) -> String {
|
||||
if ns < 0.0 {
|
||||
format!("-{}", format_ns(-ns))
|
||||
} else {
|
||||
format_ns(ns)
|
||||
}
|
||||
}
|
||||
|
||||
fn format_ns(ns: f64) -> String {
|
||||
if ns < 1_000.0 {
|
||||
format!("{ns:.0}ns")
|
||||
} else if ns < 1_000_000.0 {
|
||||
format!("{:.1}µs", ns / 1_000.0)
|
||||
} else if ns < 1_000_000_000.0 {
|
||||
format!("{:.1}ms", ns / 1_000_000.0)
|
||||
} else {
|
||||
format!("{:.3}s", ns / 1_000_000_000.0)
|
||||
}
|
||||
}
|
||||
|
||||
fn warning_kind(kind: WarningKind) -> &'static str {
|
||||
match kind {
|
||||
WarningKind::MalformedOrUnrelatedPacket => "malformed_or_unrelated_packet",
|
||||
|
||||
@@ -2,6 +2,11 @@ use std::fmt::Write as _;
|
||||
|
||||
use irtt_stats::{Snapshot, TimeStats};
|
||||
|
||||
use crate::cmd::format::{
|
||||
format_ns_f64, format_optional_ns_f64 as format_ns_f64_opt,
|
||||
format_optional_ns_i128 as format_ns_i128, format_percent,
|
||||
};
|
||||
|
||||
pub fn format_summary(summary: &Snapshot) -> String {
|
||||
format_summary_with_options(summary, SummaryFormatOptions::default())
|
||||
}
|
||||
@@ -117,34 +122,6 @@ fn write_time_row(out: &mut String, label: &str, value: &TimeStats) {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn format_percent(value: f64) -> String {
|
||||
format!("{value:.2}%")
|
||||
}
|
||||
|
||||
fn format_ns_i128(value: Option<i128>) -> String {
|
||||
value
|
||||
.map(|value| format_ns_f64(value as f64))
|
||||
.unwrap_or_else(|| "-".to_owned())
|
||||
}
|
||||
|
||||
fn format_ns_f64_opt(value: Option<f64>) -> String {
|
||||
value.map(format_ns_f64).unwrap_or_else(|| "-".to_owned())
|
||||
}
|
||||
|
||||
fn format_ns_f64(value: f64) -> String {
|
||||
let sign = if value.is_sign_negative() { "-" } else { "" };
|
||||
let value = value.abs();
|
||||
if value < 1_000.0 {
|
||||
format!("{sign}{value:.0}ns")
|
||||
} else if value < 1_000_000.0 {
|
||||
format!("{sign}{:.1}µs", value / 1_000.0)
|
||||
} else if value < 1_000_000_000.0 {
|
||||
format!("{sign}{:.1}ms", value / 1_000_000.0)
|
||||
} else {
|
||||
format!("{sign}{:.3}s", value / 1_000_000_000.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in new issue
Block a user