use regex::Regex;
use std::error::Error;
use std::fmt::Write;
use std::path::Path;
use std::{fs, io};
use walkdir::WalkDir;
fn dir_size(path: &Path) -> Result<u64, Box<dyn Error>> {
let mut size = 0;
for entry in WalkDir::new(path) {
let entry = entry?;
size += entry.metadata()?.len();
}
Ok(size)
}
pub fn total_size(root: &str, pattern: &str) -> Result<u64, Box<dyn Error>> {
if Path::new(&root).is_file() {
return Err(Box::new(io::Error::new(
io::ErrorKind::InvalidInput,
"Root can't be a file!",
)));
}
let re = Regex::new(pattern)?;
let mut total_size = 0;
for entry in fs::read_dir(root)? {
let entry = entry?;
if let Some(filename) = entry.file_name().to_str() {
if re.is_match(filename) {
if let Some(path) = entry.path().to_str() {
let mut size = 0;
if entry.file_type()?.is_file() {
size = entry.metadata()?.len();
} else if entry.file_type()?.is_dir() {
size = dir_size(&entry.path())?;
}
total_size += size;
println!("path: {path}\nsize: {size} bytes");
}
}
}
}
let mut total_size_str = String::new();
let size_kb = total_size as f64 / 1024.;
let size_mb = size_kb / 1024.;
write!(&mut total_size_str, "Total size: {total_size} bytes")?;
if size_kb > 1. {
write!(&mut total_size_str, " / {size_kb:.2} KB")?;
}
if size_mb > 1. {
write!(&mut total_size_str, " / {size_mb:.2} MB")?;
}
println!("{total_size_str}");
return Ok(total_size);
}