use super::theme::MissionControlTheme;
use crate::output::{ActivityStatus, NormalizedUsageSnapshot};
use ratatui::{style::Style, text::Span};
pub(super) const USAGE_SEPARATOR: &str = "│";
pub(super) fn usage_metric_spans(
usage: NormalizedUsageSnapshot,
cache_percent: Option<u64>,
style: Style,
theme: MissionControlTheme,
) -> [Span<'static>; 3] {
let colors = [
theme.transcript_user_color(),
theme.text_accent(),
theme.activity_status_color(ActivityStatus::Success),
];
let fields = usage_fields(usage, cache_percent);
std::array::from_fn(|index| Span::styled(fields[index].clone(), style.fg(colors[index])))
}
pub(super) fn usage_fields(
usage: NormalizedUsageSnapshot,
cache_percent: Option<u64>,
) -> [String; 3] {
[
format!("{:>4}(in)", compact_tokens(usage.effective_input)),
format!("{:>4}(out)", compact_tokens(usage.output)),
cache_percent_field(cache_percent),
]
}
pub(super) fn cache_percent_field(cache_percent: Option<u64>) -> String {
let cache = cache_percent.map_or_else(|| "—".to_string(), |percent| format!("{percent}%"));
format!("{cache:>4}(cache)")
}
pub(super) fn compact_tokens(tokens: u64) -> String {
for (scale, suffix) in [
(1_000_u64, ""),
(1_000_000, "k"),
(1_000_000_000, "M"),
(1_000_000_000_000, "G"),
(1_000_000_000_000_000, "T"),
(1_000_000_000_000_000_000, "P"),
] {
let divisor = scale / 1_000;
let rounded = (u128::from(tokens) + u128::from(divisor / 2)) / u128::from(divisor);
if rounded < 1_000 {
return format!("{rounded}{suffix}");
}
}
format!(
"{}E",
(u128::from(tokens) + 500_000_000_000_000_000) / 1_000_000_000_000_000_000
)
}