Skip to content

Commit da9ee95

Browse files
committed
free: fix humanization
1 parent fa83319 commit da9ee95

File tree

1 file changed

+39
-24
lines changed

1 file changed

+39
-24
lines changed

src/uu/free/src/free.rs

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -458,30 +458,31 @@ fn construct_committed_str(mem_info: &MemInfo, n2s: &dyn Fn(u64) -> String) -> S
458458

459459
// Here's the `-h` `--human` flag processing logic
460460
fn humanized(kib: u64, si: bool) -> String {
461-
let binding = {
462-
let display = ByteSize::kib(kib).display();
463-
464-
if si {
465-
display.si()
466-
} else {
467-
display.iec()
468-
}
461+
let b = ByteSize::kib(kib).0;
462+
let units = ['B', 'K', 'M', 'G', 'T', 'P'];
463+
let mut level = 0;
464+
let mut divisor = 1;
465+
while level < units.len() - 1 && divisor * 100 <= b {
466+
divisor *= if si { 1000 } else { 1024 };
467+
level += 1;
468+
}
469+
if level == 0 {
470+
return format!("{}{}", b, units[level]);
469471
}
470-
.to_string();
471-
472-
let split: Vec<&str> = binding.split(' ').collect();
473-
474-
// TODO: finish the logic of automatic scale.
475-
let num_string = String::from(split[0]);
476472

477-
let unit_string = {
478-
let mut tmp = String::from(split[1]);
479-
if tmp != "B" {
480-
tmp.pop();
481-
}
482-
tmp
473+
let value = (b as f64) / (divisor as f64);
474+
let formatted_value = if (value * 10.0).round() < 100.0 {
475+
format!("{:.1}", (value * 10.0).round() / 10.0)
476+
} else {
477+
(value as u64).to_string()
483478
};
484-
format!("{}{}", num_string, unit_string)
479+
480+
format!(
481+
"{}{}{}",
482+
formatted_value,
483+
units[level].to_owned(),
484+
if si { "" } else { "i" }
485+
)
485486
}
486487

487488
fn detect_unit(arg: &ArgMatches) -> fn(u64) -> u64 {
@@ -541,8 +542,22 @@ mod test {
541542
}
542543

543544
#[test]
544-
fn test_humanized_unit_for_zero() {
545-
assert_eq!("0B", humanized(0, false));
546-
assert_eq!("0B", humanized(0, true));
545+
fn test_humanized_unit() {
546+
let test_cases = [
547+
(0, false, "0B"),
548+
(0, true, "0B"),
549+
(1023, false, "1.0Mi"),
550+
(1024, true, "1.0M"),
551+
(1024, false, "1.0Mi"),
552+
(1536, true, "1.6M"),
553+
(1536, false, "1.5Mi"),
554+
(8500, true, "8.7M"),
555+
(8500, false, "8.3Mi"),
556+
(10138, false, "9.9Mi"),
557+
(10230, false, "9Mi"),
558+
];
559+
for &(kib, si, expected) in &test_cases {
560+
assert_eq!(humanized(kib, si), expected);
561+
}
547562
}
548563
}

0 commit comments

Comments
 (0)