Overhaul the thousands module.

It currently only inserts separators into `usize`s, because that's all
that has been needed so far. `-Zmacro-stats` will need `isize` and `f64`
handling, so this commit adds that.
This commit is contained in:
Nicholas Nethercote
2025-06-05 15:49:46 +10:00
parent fb73893e51
commit bdfe1b9fb0
4 changed files with 86 additions and 27 deletions

View File

@@ -1,16 +1,37 @@
//! This is an extremely bare-bones alternative to the `thousands` crate on
//! crates.io, for printing large numbers in a readable fashion.
//! This is a bare-bones alternative to the `thousands` crate on crates.io, for
//! printing large numbers in a readable fashion.
#[cfg(test)]
mod tests;
// Converts the number to a string, with underscores as the thousands separator.
pub fn format_with_underscores(n: usize) -> String {
let mut s = n.to_string();
let mut i = s.len();
while i > 3 {
fn format_with_underscores(mut s: String) -> String {
// Ignore a leading '-'.
let start = if s.starts_with('-') { 1 } else { 0 };
// Stop after the first non-digit, e.g. '.' or 'e' for floats.
let non_digit = s[start..].find(|c: char| !c.is_digit(10));
let end = if let Some(non_digit) = non_digit { start + non_digit } else { s.len() };
// Insert underscores within `start..end`.
let mut i = end;
while i > start + 3 {
i -= 3;
s.insert(i, '_');
}
s
}
/// Print a `usize` with underscore separators.
pub fn usize_with_underscores(n: usize) -> String {
format_with_underscores(format!("{n}"))
}
/// Print an `isize` with underscore separators.
pub fn isize_with_underscores(n: isize) -> String {
format_with_underscores(format!("{n}"))
}
/// Print an `f64` with precision 1 (one decimal place) and underscore separators.
pub fn f64p1_with_underscores(n: f64) -> String {
format_with_underscores(format!("{n:.1}"))
}

View File

@@ -2,13 +2,51 @@ use super::*;
#[test]
fn test_format_with_underscores() {
assert_eq!("0", format_with_underscores(0));
assert_eq!("1", format_with_underscores(1));
assert_eq!("99", format_with_underscores(99));
assert_eq!("345", format_with_underscores(345));
assert_eq!("1_000", format_with_underscores(1_000));
assert_eq!("12_001", format_with_underscores(12_001));
assert_eq!("999_999", format_with_underscores(999_999));
assert_eq!("1_000_000", format_with_underscores(1_000_000));
assert_eq!("12_345_678", format_with_underscores(12_345_678));
assert_eq!("", format_with_underscores("".to_string()));
assert_eq!("0", format_with_underscores("0".to_string()));
assert_eq!("12_345.67e14", format_with_underscores("12345.67e14".to_string()));
assert_eq!("-1_234.5678e10", format_with_underscores("-1234.5678e10".to_string()));
assert_eq!("------", format_with_underscores("------".to_string()));
assert_eq!("abcdefgh", format_with_underscores("abcdefgh".to_string()));
assert_eq!("-1b", format_with_underscores("-1b".to_string()));
assert_eq!("-3_456xyz", format_with_underscores("-3456xyz".to_string()));
}
#[test]
fn test_usize_with_underscores() {
assert_eq!("0", usize_with_underscores(0));
assert_eq!("1", usize_with_underscores(1));
assert_eq!("99", usize_with_underscores(99));
assert_eq!("345", usize_with_underscores(345));
assert_eq!("1_000", usize_with_underscores(1_000));
assert_eq!("12_001", usize_with_underscores(12_001));
assert_eq!("999_999", usize_with_underscores(999_999));
assert_eq!("1_000_000", usize_with_underscores(1_000_000));
assert_eq!("12_345_678", usize_with_underscores(12_345_678));
}
#[test]
fn test_isize_with_underscores() {
assert_eq!("0", isize_with_underscores(0));
assert_eq!("-1", isize_with_underscores(-1));
assert_eq!("99", isize_with_underscores(99));
assert_eq!("345", isize_with_underscores(345));
assert_eq!("-1_000", isize_with_underscores(-1_000));
assert_eq!("12_001", isize_with_underscores(12_001));
assert_eq!("-999_999", isize_with_underscores(-999_999));
assert_eq!("1_000_000", isize_with_underscores(1_000_000));
assert_eq!("-12_345_678", isize_with_underscores(-12_345_678));
}
#[test]
fn test_f64p1_with_underscores() {
assert_eq!("0.0", f64p1_with_underscores(0f64));
assert_eq!("0.0", f64p1_with_underscores(0.00000001));
assert_eq!("-0.0", f64p1_with_underscores(-0.00000001));
assert_eq!("1.0", f64p1_with_underscores(0.9999999));
assert_eq!("-1.0", f64p1_with_underscores(-0.9999999));
assert_eq!("345.5", f64p1_with_underscores(345.4999999));
assert_eq!("-100_000.0", f64p1_with_underscores(-100_000f64));
assert_eq!("123_456_789.1", f64p1_with_underscores(123456789.123456789));
assert_eq!("-123_456_789.1", f64p1_with_underscores(-123456789.123456789));
}