pub fn int(n: usize) -> String {
let s = n.to_string();
let mut out = String::new();
for (i, c) in s.chars().enumerate() {
if i > 0 && (s.len() - i).is_multiple_of(3) {
out.push(',');
}
out.push(c);
}
out
}
pub fn tokens(n: u64) -> String {
const UNITS: [(f64, &str); 3] = [(1e9, "B"), (1e6, "M"), (1e3, "K")];
for (u, s) in UNITS {
let v = n as f64 / u;
if v >= 1.0 {
return if v >= 100.0 {
format!("{v:.0}{s}")
} else if v >= 10.0 {
format!("{v:.1}{s}")
} else {
format!("{v:.2}{s}")
};
}
}
n.to_string()
}
pub fn money(x: f64) -> String {
if x != 0.0 && x.abs() < 0.005 {
return "<$0.01".to_string();
}
let neg = x < 0.0;
let x = x.abs();
let int_part = x.trunc() as u64;
let frac = ((x.fract() * 100.0).round() as u64).min(99);
let digits = int_part.to_string();
let mut grouped = String::new();
for (i, c) in digits.chars().enumerate() {
if i > 0 && (digits.len() - i).is_multiple_of(3) {
grouped.push(',');
}
grouped.push(c);
}
format!("{}${grouped}.{frac:02}", if neg { "-" } else { "" })
}
pub fn datetime(ts: chrono::DateTime<chrono::Utc>) -> String {
ts.with_timezone(&chrono::Local)
.format("%b %d %H:%M")
.to_string()
}