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 const 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 const 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 const fn nice_time_unit(seconds: f64) -> Self {
56 let mut i = TimeUnit::VALUES.len();
57 while i > 0 {
58 i -= 1;
59 if seconds >= TimeUnit::VALUES[i].as_seconds() {
60 return TimeUnit::VALUES[i];
61 }
62 }
63 TimeUnit::NanoSeconds
64 }
65
66 pub const fn nice_speed_unit(seconds: f64) -> Self {
67 let mut i = 3;
68 while i < TimeUnit::VALUES.len() {
69 if seconds <= TimeUnit::VALUES[i].as_seconds() {
70 return TimeUnit::VALUES[i];
71 }
72 i += 1;
73 }
74 TimeUnit::Days
75 }
76
77 pub fn pretty_print(milliseconds: u128) -> String {
78 let mut result = String::new();
79
80 if milliseconds < 1000 {
81 return format!("{}ms", milliseconds);
82 }
83
84 let mut seconds = milliseconds / 1000;
85
86 for unit in [TimeUnit::Days, TimeUnit::Hours, TimeUnit::Minutes] {
87 let to_seconds = unit.as_seconds() as u128;
88 if seconds >= to_seconds {
89 result.push_str(&format!("{}{} ", seconds / to_seconds, unit.label(),));
90 seconds %= to_seconds;
91 }
92 }
93
94 result.push_str(&format!("{}s", seconds));
95
96 result
97 }
98}
99
100pub const fn scale(mut val: f64) -> (f64, &'static str) {
101 const UNITS: &[&str] = &["", "k", "M", "G", "T", "P", "E", "Z", "Y"];
102 let mut i = 0;
103 while i < UNITS.len() {
104 if val < 1000.0 {
105 return (val, UNITS[i]);
106 }
107 val /= 1000.0;
108 i += 1;
109 }
110
111 (val, "Y")
112}
113
114pub fn humanize(val: f64) -> String {
115 let (val, unit) = scale(val);
116 format!("{:.2}{}", val, unit)
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 #[test]
123 fn test_scale() {
124 assert_eq!(scale(1000.0), (1.0, "k"));
125 assert_eq!(scale(300_000.0), (300.0, "k"));
126 assert_eq!(scale(1_000_000_000.0), (1.0, "G"));
127 }
128 #[test]
129
130 fn test_humanize() {
131 assert_eq!(humanize(1000.0), "1.00k");
132 assert_eq!(humanize(12_345.0), "12.35k");
133 assert_eq!(humanize(1_234_567_890.0), "1.23G");
134 }
135}