1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 19:47:45 +00:00

df: fix "Size" column header

Fixes #3193
This commit is contained in:
Daniel Hofstetter 2022-04-28 09:10:20 +02:00
parent f03c069289
commit 023fc96aab
2 changed files with 75 additions and 33 deletions

View file

@ -26,6 +26,22 @@ const IEC_BASES: [u128; 10] = [
/// Suffixes for the first nine multi-byte unit suffixes. /// Suffixes for the first nine multi-byte unit suffixes.
const SUFFIXES: [char; 9] = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; const SUFFIXES: [char; 9] = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
const SI_BASES: [u128; 10] = [
1,
1_000,
1_000_000,
1_000_000_000,
1_000_000_000_000,
1_000_000_000_000_000,
1_000_000_000_000_000_000,
1_000_000_000_000_000_000_000,
1_000_000_000_000_000_000_000_000,
1_000_000_000_000_000_000_000_000_000,
];
// we use "kB" instead of "KB" because of GNU df
const SI_SUFFIXES: [&str; 9] = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
/// Convert a multiple of 1024 into a string like "12K" or "34M". /// Convert a multiple of 1024 into a string like "12K" or "34M".
/// ///
/// # Examples /// # Examples
@ -57,6 +73,37 @@ fn to_magnitude_and_suffix_1024(n: u128) -> Result<String, ()> {
Err(()) Err(())
} }
/// Convert a number, except multiples of 1024, into a string like "12kB" or "34MB".
///
/// Powers of 1000 become "1kB", "1MB", "1GB", etc.
///
/// The returned string has a maximum length of 5 chars, for example: "1.1kB", "999kB", "1MB".
fn to_magnitude_and_suffix_not_powers_of_1024(n: u128) -> Result<String, ()> {
let mut i = 0;
while SI_BASES[i + 1] - SI_BASES[i] < n && i < SI_SUFFIXES.len() {
i += 1;
}
let quot = n / SI_BASES[i];
let rem = n % SI_BASES[i];
let suffix = SI_SUFFIXES[i];
if rem == 0 {
Ok(format!("{}{}", quot, suffix))
} else {
let tenths_place = rem / (SI_BASES[i] / 10);
if rem % (SI_BASES[i] / 10) == 0 {
Ok(format!("{}.{}{}", quot, tenths_place, suffix))
} else if tenths_place + 1 == 10 {
Ok(format!("{}{}", quot + 1, suffix))
} else {
Ok(format!("{}.{}{}", quot, tenths_place + 1, suffix))
}
}
}
/// Convert a number into a magnitude and a multi-byte unit suffix. /// Convert a number into a magnitude and a multi-byte unit suffix.
/// ///
/// # Errors /// # Errors
@ -66,8 +113,7 @@ fn to_magnitude_and_suffix(n: u128) -> Result<String, ()> {
if n % 1024 == 0 { if n % 1024 == 0 {
to_magnitude_and_suffix_1024(n) to_magnitude_and_suffix_1024(n)
} else { } else {
// TODO Implement this, probably using code from `numfmt`. to_magnitude_and_suffix_not_powers_of_1024(n)
Ok("1kB".into())
} }
} }
@ -153,36 +199,33 @@ mod tests {
); );
} }
// TODO We have not yet implemented this behavior, but when we do, #[test]
// uncomment this test. fn test_to_magnitude_and_suffix_not_powers_of_1024() {
assert_eq!(to_magnitude_and_suffix(1).unwrap(), "1B");
assert_eq!(to_magnitude_and_suffix(999).unwrap(), "999B");
// #[test] assert_eq!(to_magnitude_and_suffix(1000).unwrap(), "1kB");
// fn test_to_magnitude_and_suffix_not_powers_of_1024() { assert_eq!(to_magnitude_and_suffix(1001).unwrap(), "1.1kB");
// assert_eq!(to_magnitude_and_suffix(1).unwrap(), "1B"); assert_eq!(to_magnitude_and_suffix(1023).unwrap(), "1.1kB");
// assert_eq!(to_magnitude_and_suffix(999).unwrap(), "999B"); assert_eq!(to_magnitude_and_suffix(1025).unwrap(), "1.1kB");
assert_eq!(to_magnitude_and_suffix(999_000).unwrap(), "999kB");
// assert_eq!(to_magnitude_and_suffix(1000).unwrap(), "1kB"); assert_eq!(to_magnitude_and_suffix(999_001).unwrap(), "1MB");
// assert_eq!(to_magnitude_and_suffix(1001).unwrap(), "1.1kB"); assert_eq!(to_magnitude_and_suffix(999_999).unwrap(), "1MB");
// assert_eq!(to_magnitude_and_suffix(1023).unwrap(), "1.1kB"); assert_eq!(to_magnitude_and_suffix(1_000_000).unwrap(), "1MB");
// assert_eq!(to_magnitude_and_suffix(1025).unwrap(), "1.1kB"); assert_eq!(to_magnitude_and_suffix(1_000_001).unwrap(), "1.1MB");
// assert_eq!(to_magnitude_and_suffix(999_000).unwrap(), "999kB"); assert_eq!(to_magnitude_and_suffix(1_100_000).unwrap(), "1.1MB");
assert_eq!(to_magnitude_and_suffix(1_100_001).unwrap(), "1.2MB");
assert_eq!(to_magnitude_and_suffix(1_900_000).unwrap(), "1.9MB");
assert_eq!(to_magnitude_and_suffix(1_900_001).unwrap(), "2MB");
assert_eq!(to_magnitude_and_suffix(9_900_000).unwrap(), "9.9MB");
assert_eq!(to_magnitude_and_suffix(9_900_001).unwrap(), "10MB");
assert_eq!(to_magnitude_and_suffix(999_000_000).unwrap(), "999MB");
// assert_eq!(to_magnitude_and_suffix(999_001).unwrap(), "1MB"); assert_eq!(to_magnitude_and_suffix(999_000_001).unwrap(), "1GB");
// assert_eq!(to_magnitude_and_suffix(999_999).unwrap(), "1MB"); assert_eq!(to_magnitude_and_suffix(1_000_000_000).unwrap(), "1GB");
// assert_eq!(to_magnitude_and_suffix(1_000_000).unwrap(), "1MB"); assert_eq!(to_magnitude_and_suffix(1_000_000_001).unwrap(), "1.1GB");
// assert_eq!(to_magnitude_and_suffix(1_000_001).unwrap(), "1.1MB"); }
// assert_eq!(to_magnitude_and_suffix(1_100_000).unwrap(), "1.1MB");
// assert_eq!(to_magnitude_and_suffix(1_100_001).unwrap(), "1.2MB");
// assert_eq!(to_magnitude_and_suffix(1_900_000).unwrap(), "1.9MB");
// assert_eq!(to_magnitude_and_suffix(1_900_001).unwrap(), "2MB");
// assert_eq!(to_magnitude_and_suffix(9_900_000).unwrap(), "9.9MB");
// assert_eq!(to_magnitude_and_suffix(9_900_001).unwrap(), "10MB");
// assert_eq!(to_magnitude_and_suffix(999_000_000).unwrap(), "999MB");
// assert_eq!(to_magnitude_and_suffix(999_000_001).unwrap(), "1GB");
// assert_eq!(to_magnitude_and_suffix(1_000_000_000).unwrap(), "1GB");
// // etc.
// }
#[test] #[test]
fn test_block_size_display() { fn test_block_size_display() {

View file

@ -413,10 +413,9 @@ fn test_block_size_with_suffix() {
assert_eq!(get_header("1KiB"), "1K-blocks"); assert_eq!(get_header("1KiB"), "1K-blocks");
assert_eq!(get_header("1MiB"), "1M-blocks"); assert_eq!(get_header("1MiB"), "1M-blocks");
assert_eq!(get_header("1GiB"), "1G-blocks"); assert_eq!(get_header("1GiB"), "1G-blocks");
// TODO enable the following asserts when #3193 is resolved assert_eq!(get_header("1KB"), "1kB-blocks");
//assert_eq!(get_header("1KB"), "1kB-blocks"); assert_eq!(get_header("1MB"), "1MB-blocks");
//assert_eq!(get_header("1MB"), "1MB-blocks"); assert_eq!(get_header("1GB"), "1GB-blocks");
//assert_eq!(get_header("1GB"), "1GB-blocks");
} }
#[test] #[test]