dsi_progress_logger/
utils.rs1#[derive(Debug, Copy, Clone)]
9
10pub enum TimeUnit {
11 NanoSeconds,
12 MicroSeconds,
13 MilliSeconds,
14 Seconds,
15 Minutes,
16 Hours,
17 Days,
18}
19
20impl TimeUnit {
21 pub const VALUES: [TimeUnit; 7] = [
22 TimeUnit::NanoSeconds,
23 TimeUnit::MicroSeconds,
24 TimeUnit::MilliSeconds,
25 TimeUnit::Seconds,
26 TimeUnit::Minutes,
27 TimeUnit::Hours,
28 TimeUnit::Days,
29 ];
30
31 pub fn label(&self) -> &'static str {
32 match self {
33 TimeUnit::NanoSeconds => "ns",
34 TimeUnit::MicroSeconds => "μs",
35 TimeUnit::MilliSeconds => "ms",
36 TimeUnit::Seconds => "s",
37 TimeUnit::Minutes => "m",
38 TimeUnit::Hours => "h",
39 TimeUnit::Days => "d",
40 }
41 }
42
43 pub fn as_seconds(&self) -> f64 {
44 match self {
45 TimeUnit::NanoSeconds => 1.0e-9,
46 TimeUnit::MicroSeconds => 1.0e-6,
47 TimeUnit::MilliSeconds => 1.0e-3,
48 TimeUnit::Seconds => 1.0,
49 TimeUnit::Minutes => 60.0,
50 TimeUnit::Hours => 3600.0,
51 TimeUnit::Days => 86400.0,
52 }
53 }
54
55 pub fn nice_time_unit(seconds: f64) -> Self {
56 for unit in TimeUnit::VALUES.iter().rev() {
57 if seconds >= unit.as_seconds() {
58 return *unit;
59 }
60 }
61 TimeUnit::NanoSeconds
62 }
63
64 pub fn nice_speed_unit(seconds: f64) -> Self {
65 for unit in TimeUnit::VALUES[3..].iter() {
66 if seconds <= unit.as_seconds() {
67 return *unit;
68 }
69 }
70 TimeUnit::Days
71 }
72
73 pub fn pretty_print(milliseconds: u128) -> String {
74 let mut result = String::new();
75
76 if milliseconds < 1000 {
77 return format!("{}ms", milliseconds);
78 }
79
80 let mut seconds = milliseconds / 1000;
81
82 for unit in [TimeUnit::Days, TimeUnit::Hours, TimeUnit::Minutes] {
83 let to_seconds = unit.as_seconds() as u128;
84 if seconds >= to_seconds {
85 result.push_str(&format!("{}{} ", seconds / to_seconds, unit.label(),));
86 seconds %= to_seconds;
87 }
88 }
89
90 result.push_str(&format!("{}s", seconds));
91
92 result
93 }
94}
95
96pub fn scale(mut val: f64) -> (f64, &'static str) {
97 const UNITS: &[&str] = &["", "k", "M", "G", "T", "P", "E", "Z", "Y"];
98 for unit in UNITS.iter() {
99 if val < 1000.0 {
100 return (val, unit);
101 }
102 val /= 1000.0;
103 }
104
105 (val, "Y")
106}
107
108pub fn humanize(val: f64) -> String {
109 let (val, unit) = scale(val);
110 format!("{:.2}{}", val, unit)
111}
112
113#[cfg(test)]
114
115mod test {
116 use super::*;
117 #[test]
118 fn test_scale() {
119 assert_eq!(scale(1000.0), (1.0, "k"));
120 assert_eq!(scale(300_000.0), (300.0, "k"));
121 assert_eq!(scale(1_000_000_000.0), (1.0, "G"));
122 }
123 #[test]
124
125 fn test_humanize() {
126 assert_eq!(humanize(1000.0), "1.00k");
127 assert_eq!(humanize(12_345.0), "12.35k");
128 assert_eq!(humanize(1_234_567_890.0), "1.23G");
129 }
130}