pub fn fmt_tokens(n: u64) -> String {
if n >= 1_000_000 {
format!("{:.1}m", n as f64 / 1_000_000.0)
} else if n >= 1_000 {
format!("{}k", n / 1_000)
} else {
n.to_string()
}
}
pub fn fmt_countdown(secs: i64) -> String {
if secs < 60 {
"<1m".to_string()
} else if secs < 3600 {
format!("{}m", secs / 60)
} else if secs < 86_400 {
format!("{}h {}m", secs / 3600, (secs % 3600) / 60)
} else {
format!("{}d {}h", secs / 86_400, (secs % 86_400) / 3600)
}
}
pub struct Style {
pub track: u8,
pub dim: u8,
pub fill: u8,
pub width: usize,
pub filled: String,
pub empty: String,
pub braille: bool,
}
pub fn filled_cells(pct: u8, width: usize) -> usize {
(pct.min(100) as usize * width + 50) / 100
}
pub fn bar_colored(bar_pct: u8, color: u8, s: &Style) -> String {
if s.braille {
return braille_bar(bar_pct, color, s);
}
let f = filled_cells(bar_pct, s.width);
let e = s.width - f;
let mut out = format!("\x1b[38;5;{}m", color);
for _ in 0..f {
out.push_str(&s.filled);
}
out.push_str(&format!("\x1b[38;5;{}m", s.track));
for _ in 0..e {
out.push_str(&s.empty);
}
out.push_str("\x1b[0m");
out
}
fn braille_bar(bar_pct: u8, color: u8, s: &Style) -> String {
let subcols = 2 * s.width;
let filled = (bar_pct.min(100) as usize * subcols + 50) / 100;
let fill_c = format!("\x1b[38;5;{}m", color);
let track_c = format!("\x1b[38;5;{}m", s.track);
let mut out = String::new();
for cell in 0..s.width {
let left = 2 * cell < filled;
let right = 2 * cell + 1 < filled;
let mut bits: u32 = 0xC0; if left {
bits |= 0x07; }
if right {
bits |= 0x38; }
let glyph = char::from_u32(0x2800 + bits).unwrap_or('⣀');
out.push_str(if left || right { &fill_c } else { &track_c });
out.push(glyph);
}
out.push_str("\x1b[0m");
out
}
pub fn bar(pct: u8, s: &Style) -> String {
bar_colored(pct, s.fill, s)
}
pub fn header(model: &str, plan: &str, s: &Style) -> String {
if plan.is_empty() {
format!("\x1b[1m{model}\x1b[0m")
} else {
format!("\x1b[1m{model}\x1b[0m \x1b[38;5;{dim}m{plan}\x1b[0m", dim = s.dim)
}
}
pub fn row(label: &str, pct: Option<u8>, value: &str, s: &Style) -> String {
let dim = format!("\x1b[38;5;{}m", s.dim);
let (pdisp, bar_pct) = match pct {
None => (format!("{:>4}", "--"), 0u8),
Some(p) => (format!("{:>3}%", p), p),
};
format!(
"\x1b[1m{label:<8}\x1b[0m {barstr} {dim}{pdisp}\x1b[0m {dim}{value}\x1b[0m",
barstr = bar(bar_pct, s),
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn formats_tokens() {
assert_eq!(fmt_tokens(0), "0");
assert_eq!(fmt_tokens(999), "999");
assert_eq!(fmt_tokens(1_000), "1k");
assert_eq!(fmt_tokens(15_500), "15k");
assert_eq!(fmt_tokens(1_000_000), "1.0m");
assert_eq!(fmt_tokens(1_500_000), "1.5m");
}
#[test]
fn formats_countdown() {
assert_eq!(fmt_countdown(30), "<1m");
assert_eq!(fmt_countdown(45 * 60), "45m");
assert_eq!(fmt_countdown(2 * 3600 + 15 * 60), "2h 15m");
assert_eq!(fmt_countdown(4 * 86_400 + 6 * 3600), "4d 6h");
assert_eq!(fmt_countdown(60), "1m"); assert_eq!(fmt_countdown(3600), "1h 0m"); assert_eq!(fmt_countdown(86_400), "1d 0h"); }
fn test_style() -> Style {
Style {
track: 240,
dim: 245,
fill: 68,
width: 12,
filled: "#".into(),
empty: ".".into(),
braille: false,
}
}
#[test]
fn computes_filled_cells() {
assert_eq!(filled_cells(0, 12), 0);
assert_eq!(filled_cells(100, 12), 12);
assert_eq!(filled_cells(50, 12), 6);
assert_eq!(filled_cells(99, 12), 12);
assert_eq!(filled_cells(4, 12), 0);
assert_eq!(filled_cells(8, 12), 1);
assert_eq!(filled_cells(200, 12), 12);
}
#[test]
fn bar_uses_brand_fill() {
let s = test_style();
let b = bar(50, &s);
assert!(b.starts_with("\x1b[38;5;68m")); assert_eq!(b.matches('#').count(), 6);
assert_eq!(b.matches('.').count(), 6);
assert!(b.ends_with("\x1b[0m"));
}
#[test]
fn braille_bar_renders_dots() {
let mut s = test_style();
s.braille = true;
assert_eq!(bar(100, &s).matches('⣿').count(), 12);
assert_eq!(bar(0, &s).matches('⣀').count(), 12);
let mid = bar(50, &s);
assert_eq!(mid.matches('⣿').count(), 6);
assert_eq!(mid.matches('⣀').count(), 6);
assert!(mid.starts_with("\x1b[38;5;68m"));
assert!(mid.ends_with("\x1b[0m"));
}
#[test]
fn header_is_bold() {
let s = test_style();
assert_eq!(header("Opus 4.8", "", &s), "\x1b[1mOpus 4.8\x1b[0m");
let with_plan = header("Opus 4.8", "Max (20x)", &s);
assert!(with_plan.starts_with("\x1b[1mOpus 4.8\x1b[0m"));
assert!(with_plan.contains("Max (20x)"));
}
#[test]
fn row_with_pct() {
let s = test_style();
let r = row("5h", Some(42), "resets in 2h 15m", &s);
assert!(r.contains("\x1b[1m5h \x1b[0m")); assert!(r.contains(" 42%")); assert!(r.contains("resets in 2h 15m"));
}
#[test]
fn row_without_pct() {
let s = test_style();
let r = row("7d", None, "--", &s);
assert!(r.contains(" --"));
assert!(!r.contains('%'));
}
}