Skip to main content

jt_consoleutils/
str_utils.rs

1use std::path::Path;
2
3/// Format a byte count as a human-readable string with one decimal place.
4/// Examples: `"0 B"`, `"512 B"`, `"1.0 KB"`, `"3.5 MB"`, `"1.2 GB"`.
5pub fn format_bytes(bytes: u64) -> String {
6   const KB: u64 = 1024;
7   const MB: u64 = 1024 * KB;
8   const GB: u64 = 1024 * MB;
9
10   if bytes >= GB {
11      format!("{:.1} GB", bytes as f64 / GB as f64)
12   } else if bytes >= MB {
13      format!("{:.1} MB", bytes as f64 / MB as f64)
14   } else if bytes >= KB {
15      format!("{:.1} KB", bytes as f64 / KB as f64)
16   } else {
17      format!("{bytes} B")
18   }
19}
20
21/// Convert a `Path` to a `String` via `display()`.
22pub fn path_to_string(path: &Path) -> String {
23   path.display().to_string()
24}
25
26/// Returns `""` when `n == 1`, otherwise `"s"`.
27pub fn plural(n: usize) -> &'static str {
28   if n == 1 { "" } else { "s" }
29}
30
31#[cfg(test)]
32mod tests {
33   use super::*;
34
35   #[test]
36   fn path_to_string_converts_path() {
37      // Given
38      let path = Path::new("/some/path/file.ts");
39
40      // When
41      let s = path_to_string(path);
42
43      // Then
44      assert_eq!(s, "/some/path/file.ts");
45   }
46
47   // -------------------------------------------------------------------------
48   // format_bytes
49   // -------------------------------------------------------------------------
50
51   #[test]
52   fn format_bytes_bytes() {
53      assert_eq!(format_bytes(0), "0 B");
54      assert_eq!(format_bytes(512), "512 B");
55      assert_eq!(format_bytes(1023), "1023 B");
56   }
57
58   #[test]
59   fn format_bytes_kilobytes() {
60      assert_eq!(format_bytes(1024), "1.0 KB");
61      assert_eq!(format_bytes(1536), "1.5 KB");
62   }
63
64   #[test]
65   fn format_bytes_megabytes() {
66      assert_eq!(format_bytes(1_048_576), "1.0 MB");
67      assert_eq!(format_bytes(1_572_864), "1.5 MB");
68   }
69
70   #[test]
71   fn format_bytes_gigabytes() {
72      assert_eq!(format_bytes(1_073_741_824), "1.0 GB");
73      assert_eq!(format_bytes(1_610_612_736), "1.5 GB");
74   }
75
76   // -------------------------------------------------------------------------
77   // plural
78   // -------------------------------------------------------------------------
79
80   #[test]
81   fn plural_singular() {
82      assert_eq!(plural(1), "");
83   }
84
85   #[test]
86   fn plural_plural() {
87      assert_eq!(plural(2), "s");
88   }
89
90   #[test]
91   fn plural_zero() {
92      assert_eq!(plural(0), "s");
93   }
94}