tree_rust/
format.rs

1use std::time::SystemTime;
2use chrono::{DateTime, Local};
3
4/// Format file size in human-readable format
5pub fn format_size(size: u64, si: bool) -> String {
6    let units = if si {
7        ["B", "kB", "MB", "GB", "TB", "PB"]
8    } else {
9        ["B", "K", "M", "G", "T", "P"]
10    };
11    let base: f64 = if si { 1000.0 } else { 1024.0 };
12
13    if size < base as u64 {
14        return format!("{:>4}", size);
15    }
16
17    let mut size_f = size as f64;
18    let mut unit_idx = 0;
19
20    while size_f >= base && unit_idx < units.len() - 1 {
21        size_f /= base;
22        unit_idx += 1;
23    }
24
25    if size_f >= 10.0 {
26        format!("{:>3.0}{}", size_f, units[unit_idx])
27    } else {
28        format!("{:>3.1}{}", size_f, units[unit_idx])
29    }
30}
31
32/// Format timestamp for display
33pub fn format_time(time: SystemTime, format: Option<&str>) -> String {
34    let datetime: DateTime<Local> = time.into();
35    let fmt = format.unwrap_or("%b %d %H:%M");
36    datetime.format(fmt).to_string()
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn test_format_size_bytes() {
45        assert_eq!(format_size(0, false).trim(), "0");
46        assert_eq!(format_size(512, false).trim(), "512");
47    }
48
49    #[test]
50    fn test_format_size_kilobytes() {
51        assert_eq!(format_size(1024, false).trim(), "1.0K");
52        assert_eq!(format_size(2048, false).trim(), "2.0K");
53    }
54
55    #[test]
56    fn test_format_size_si() {
57        assert_eq!(format_size(1000, true).trim(), "1.0kB");
58        assert_eq!(format_size(1500, true).trim(), "1.5kB");
59    }
60}