Skip to content

Commit 6414861

Browse files
authored
Merge pull request #1021 from MaxVerevkin/new_format_number
Fix format_number function
2 parents 99ff12a + 7cf64b1 commit 6414861

File tree

1 file changed

+38
-40
lines changed

1 file changed

+38
-40
lines changed

src/util.rs

+38-40
Original file line numberDiff line numberDiff line change
@@ -36,42 +36,26 @@ pub fn escape_pango_text(text: String) -> String {
3636
.collect()
3737
}
3838

39-
pub fn format_number(raw_value: f64, total_digits: usize, min_unit: &str, suffix: &str) -> String {
40-
let (min_unit_value, min_unit_level) = match min_unit {
41-
"T" => (raw_value / 1_000_000_000_000.0, 4),
42-
"G" => (raw_value / 1_000_000_000.0, 3),
43-
"M" => (raw_value / 1_000_000.0, 2),
44-
"K" => (raw_value / 1_000.0, 1),
45-
"1" => (raw_value, 0),
46-
"m" => (raw_value * 1_000.0, -1),
47-
"u" => (raw_value * 1_000_000.0, -2),
48-
"n" => (raw_value * 1_000_000_000.0, -3),
49-
_ => (raw_value * 1_000_000_000_000.0, -4),
39+
/// Format `raw_value` to engineering notation
40+
pub fn format_number(raw_value: f64, total_digits: usize, min_suffix: &str, unit: &str) -> String {
41+
let min_exp_level = match min_suffix {
42+
"T" => 4,
43+
"G" => 3,
44+
"M" => 2,
45+
"K" => 1,
46+
"1" => 0,
47+
"m" => -1,
48+
"u" => -2,
49+
"n" => -3,
50+
_ => -4,
5051
};
5152

52-
//println!("Min Unit: ({}, {})", min_unit_value, min_unit_level);
53-
54-
let (magnitude_value, magnitude_level) = match raw_value {
55-
x if x >= 100_000_000_000.0 => (raw_value / 1_000_000_000_000.0, 4),
56-
x if x >= 100_000_000.0 => (raw_value / 1_000_000_000.0, 3),
57-
x if x >= 100_000.0 => (raw_value / 1_000_000.0, 2),
58-
x if x >= 100.0 => (raw_value / 1_000.0, 1),
59-
x if x >= 0.1 => (raw_value, 0),
60-
x if x >= 0.000_1 => (raw_value * 1_000.0, -1),
61-
x if x >= 0.000_000_1 => (raw_value * 1_000_000.0, -2),
62-
x if x >= 0.000_000_000_1 => (raw_value * 1_000_000_000.0, -3),
63-
_ => (raw_value * 1_000_000_000_000.0, -4),
64-
};
65-
66-
//println!("Magnitude: ({}, {})", magnitude_value, magnitude_level);
67-
68-
let (value, level) = if magnitude_level < min_unit_level {
69-
(min_unit_value, min_unit_level)
70-
} else {
71-
(magnitude_value, magnitude_level)
72-
};
53+
let exp_level = (raw_value.log10().div_euclid(3.) as i32)
54+
.max(min_exp_level)
55+
.min(4);
56+
let value = raw_value / (10f64).powi(exp_level * 3);
7357

74-
let unit = match level {
58+
let suffix = match exp_level {
7559
4 => "T",
7660
3 => "G",
7761
2 => "M",
@@ -83,14 +67,17 @@ pub fn format_number(raw_value: f64, total_digits: usize, min_unit: &str, suffix
8367
_ => "p",
8468
};
8569

86-
let _decimal_precision = total_digits as i16 - if value >= 10.0 { 2 } else { 1 };
87-
let decimal_precision = if _decimal_precision < 0 {
88-
0
70+
let total_digits = total_digits as isize;
71+
let decimals = (if value >= 100. {
72+
total_digits - 3
73+
} else if value >= 10. {
74+
total_digits - 2
8975
} else {
90-
_decimal_precision
91-
};
76+
total_digits - 1
77+
})
78+
.max(0);
9279

93-
format!("{:.*}{}{}", decimal_precision as usize, value, unit, suffix)
80+
format!("{:.*}{}{}", decimals as usize, value, suffix, unit)
9481
}
9582

9683
pub fn battery_level_to_icon(charge_level: Result<u64>) -> &'static str {
@@ -512,7 +499,18 @@ macro_rules! if_debug {
512499

513500
#[cfg(test)]
514501
mod tests {
515-
use crate::util::{color_from_rgba, has_command};
502+
use crate::util::{color_from_rgba, format_number, has_command};
503+
504+
#[test]
505+
fn test_format_number() {
506+
assert_eq!(format_number(1.0, 3, "", "s"), "1.00s");
507+
assert_eq!(format_number(1.007, 3, "", "s"), "1.01s");
508+
assert_eq!(format_number(1.007, 4, "K", "s"), "0.001Ks");
509+
assert_eq!(format_number(1007., 3, "K", "s"), "1.01Ks");
510+
assert_eq!(format_number(107_000., 3, "", "s"), "107Ks");
511+
assert_eq!(format_number(107., 3, "", "s"), "107s");
512+
assert_eq!(format_number(0.000_123_123, 3, "", "N"), "123uN");
513+
}
516514

517515
#[test]
518516
// we assume sh is always available

0 commit comments

Comments
 (0)