@@ -36,42 +36,24 @@ pub fn escape_pango_text(text: String) -> String {
36
36
. collect ( )
37
37
}
38
38
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 ,
50
51
} ;
51
52
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 ) . max ( min_exp_level) ;
54
+ let value = raw_value / ( 10f64 ) . powi ( exp_level * 3 ) ;
73
55
74
- let unit = match level {
56
+ let suffix = match exp_level {
75
57
4 => "T" ,
76
58
3 => "G" ,
77
59
2 => "M" ,
@@ -83,14 +65,17 @@ pub fn format_number(raw_value: f64, total_digits: usize, min_unit: &str, suffix
83
65
_ => "p" ,
84
66
} ;
85
67
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
68
+ let total_digits = total_digits as isize ;
69
+ let decimals = ( if value >= 100. {
70
+ total_digits - 3
71
+ } else if value >= 10. {
72
+ total_digits - 2
89
73
} else {
90
- _decimal_precision
91
- } ;
74
+ total_digits - 1
75
+ } )
76
+ . max ( 0 ) ;
92
77
93
- format ! ( "{:.*}{}{}" , decimal_precision as usize , value, unit , suffix )
78
+ format ! ( "{:.*}{}{}" , decimals as usize , value, suffix , unit )
94
79
}
95
80
96
81
pub fn battery_level_to_icon ( charge_level : Result < u64 > ) -> & ' static str {
@@ -512,7 +497,18 @@ macro_rules! if_debug {
512
497
513
498
#[ cfg( test) ]
514
499
mod tests {
515
- use crate :: util:: { color_from_rgba, has_command} ;
500
+ use crate :: util:: { color_from_rgba, format_number, has_command} ;
501
+
502
+ #[ test]
503
+ fn test_format_number ( ) {
504
+ //assert_eq!(format_number(1.0, 3, "", "s"), "1.00s");
505
+ //assert_eq!(format_number(1.007, 3, "", "s"), "1.01s");
506
+ //assert_eq!(format_number(1.007, 4, "K", "s"), "0.001Ks");
507
+ //assert_eq!(format_number(1007., 3, "K", "s"), "1.01Ks");
508
+ //assert_eq!(format_number(107_000., 3, "", "s"), "107Ks");
509
+ //assert_eq!(format_number(107., 3, "", "s"), "107s");
510
+ assert_eq ! ( format_number( 0.000_123_123 , 3 , "" , "N" ) , "123uN" ) ;
511
+ }
516
512
517
513
#[ test]
518
514
// we assume sh is always available
0 commit comments