mi6_cli/display/
format.rs1pub fn format_number(n: i64) -> String {
5 let s = n.to_string();
6 let mut result = String::new();
7 let chars: Vec<char> = s.chars().collect();
8
9 for (i, c) in chars.iter().enumerate() {
10 if i > 0 && (chars.len() - i).is_multiple_of(3) {
11 result.push(',');
12 }
13 result.push(*c);
14 }
15
16 result
17}
18
19pub fn format_bytes(bytes: u64) -> String {
21 const KB: u64 = 1024;
22 const MB: u64 = KB * 1024;
23 const GB: u64 = MB * 1024;
24
25 if bytes >= GB {
26 format!("{:.1} GB", bytes as f64 / GB as f64)
27 } else if bytes >= MB {
28 format!("{:.1} MB", bytes as f64 / MB as f64)
29 } else if bytes >= KB {
30 format!("{:.1} KB", bytes as f64 / KB as f64)
31 } else {
32 format!("{} B", bytes)
33 }
34}
35
36pub fn format_duration(ms: i64) -> String {
38 let seconds = ms / 1000;
39 let minutes = seconds / 60;
40 let hours = minutes / 60;
41
42 if hours > 0 {
43 format!("{}h {}m {}s", hours, minutes % 60, seconds % 60)
44 } else if minutes > 0 {
45 format!("{}m {}s", minutes, seconds % 60)
46 } else {
47 format!("{}s", seconds)
48 }
49}
50
51pub fn percentage(part: i64, total: i64) -> f64 {
53 if total == 0 {
54 0.0
55 } else {
56 (part as f64 / total as f64) * 100.0
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_format_number() {
66 assert_eq!(format_number(0), "0");
67 assert_eq!(format_number(999), "999");
68 assert_eq!(format_number(1000), "1,000");
69 assert_eq!(format_number(1_000_000), "1,000,000");
70 }
71
72 #[test]
73 fn test_format_bytes_zero() {
74 assert_eq!(format_bytes(0), "0 B");
75 }
76
77 #[test]
78 fn test_format_bytes_bytes() {
79 assert_eq!(format_bytes(500), "500 B");
80 assert_eq!(format_bytes(1023), "1023 B");
81 }
82
83 #[test]
84 fn test_format_bytes_kilobytes() {
85 assert_eq!(format_bytes(1024), "1.0 KB");
86 assert_eq!(format_bytes(1536), "1.5 KB");
87 assert_eq!(format_bytes(1024 * 500), "500.0 KB");
88 }
89
90 #[test]
91 fn test_format_bytes_megabytes() {
92 assert_eq!(format_bytes(1024 * 1024), "1.0 MB");
93 assert_eq!(format_bytes(1024 * 1024 * 157), "157.0 MB");
94 }
95
96 #[test]
97 fn test_format_bytes_gigabytes() {
98 assert_eq!(format_bytes(1024 * 1024 * 1024), "1.0 GB");
99 assert_eq!(format_bytes(1024 * 1024 * 1024 * 2), "2.0 GB");
100 }
101
102 #[test]
103 fn test_format_duration() {
104 assert_eq!(format_duration(0), "0s");
105 assert_eq!(format_duration(5000), "5s");
106 assert_eq!(format_duration(65_000), "1m 5s");
107 assert_eq!(format_duration(3_665_000), "1h 1m 5s");
108 }
109
110 #[test]
111 #[expect(clippy::float_cmp)]
112 fn test_percentage() {
113 assert_eq!(percentage(0, 0), 0.0);
114 assert_eq!(percentage(50, 100), 50.0);
115 assert_eq!(percentage(1, 4), 25.0);
116 }
117}