benchmark_rs/
disk_usage.rs

1use std::path::PathBuf;
2
3/// Measure disk usage for a path
4#[allow(dead_code)]
5pub fn disk_usage(path: &PathBuf) -> std::io::Result<u64> {
6    if !path.exists() {
7        Err(std::io::Error::other(
8            format!("path does not exist: [{}]", path.to_string_lossy()),
9        ))
10    } else {
11        let mut size: u64 = 0;
12        if path.is_dir() {
13            let dir = std::fs::read_dir(path)?;
14            for result in dir.into_iter() {
15                let entry = result.unwrap();
16                size += disk_usage(&entry.path())?;
17            }
18        } else if path.is_file() {
19            size += path.metadata().unwrap().len();
20        } else {
21            // ignore
22        }
23
24        Ok(size)
25    }
26}
27
28/// Convert disk usage to human format
29#[allow(dead_code)]
30pub fn to_human(size: u64) -> String {
31    if size / 0x10000000000_u64 > 0 {
32        format!("{:.3}T", size as f64 / 0x10000000000_u64 as f64)
33    } else if size / 0x40000000_u64 > 0 {
34        format!("{:.3}G", size as f64 / 0x40000000_u64 as f64)
35    } else if size / 0x100000_u64 > 0 {
36        format!("{:.3}M", size as f64 / 0x100000_u64 as f64)
37    } else if size / 0x400_u64 > 0 {
38        format!("{:.3}K", size as f64 / 0x400_u64 as f64)
39    } else {
40        format!("{}", size)
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use crate::disk_usage::{disk_usage, to_human};
47    use std::path::PathBuf;
48
49    #[test]
50    fn test_disk_usage() -> std::io::Result<()> {
51        assert_eq!(
52            to_human(disk_usage(&PathBuf::from("./tests/fixtures/1.5K/512"))?),
53            "512".to_string()
54        );
55        assert_eq!(
56            to_human(disk_usage(&PathBuf::from("./tests/fixtures/1.5K/1K"))?),
57            "1.000K".to_string()
58        );
59        assert_eq!(
60            to_human(disk_usage(&PathBuf::from("./tests/fixtures/1.5K/"))?),
61            "1.500K".to_string()
62        );
63        Ok(())
64    }
65}