Skip to main content

diskard_core/
size.rs

1use std::path::Path;
2
3/// Format bytes into a human-readable string using binary units (e.g., "1.0 GiB").
4pub fn format_bytes(bytes: u64) -> String {
5    bytesize::ByteSize(bytes).to_string_as(true)
6}
7
8/// Calculate the total size of a directory by walking all files.
9pub fn dir_size(path: &Path) -> u64 {
10    if !path.exists() {
11        return 0;
12    }
13
14    if path.is_file() {
15        return path.metadata().map(|m| m.len()).unwrap_or(0);
16    }
17
18    jwalk::WalkDir::new(path)
19        .skip_hidden(false)
20        .into_iter()
21        .filter_map(|entry| entry.ok())
22        .filter(|entry| entry.file_type().is_file())
23        .map(|entry| entry.metadata().map(|m| m.len()).unwrap_or(0))
24        .sum()
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30
31    #[test]
32    fn test_format_bytes() {
33        assert_eq!(format_bytes(0), "0 B");
34        assert_eq!(format_bytes(1024), "1.0 kiB");
35        assert_eq!(format_bytes(1_073_741_824), "1.0 GiB");
36    }
37
38    #[test]
39    fn test_dir_size_nonexistent() {
40        assert_eq!(dir_size(Path::new("/nonexistent/path")), 0);
41    }
42}