use crate::scanner::{walker::age_days, FsNode};
use serde::Serialize;
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize)]
pub struct StaleFile {
pub path: PathBuf,
pub size: u64,
pub days_since_access: i64,
}
pub fn stale_files(root: &FsNode, min_days: i64, min_size: u64) -> Vec<StaleFile> {
let mut files = Vec::new();
root.flatten_files(&mut files);
let mut out: Vec<StaleFile> = files.into_iter()
.filter(|f| f.size >= min_size)
.filter_map(|f| {
let acc = f.accessed?;
let days = age_days(acc);
if days >= min_days {
Some(StaleFile { path: f.path.clone(), size: f.size, days_since_access: days })
} else {
None
}
})
.collect();
out.sort_by(|a, b| b.size.cmp(&a.size));
out
}
pub fn old_files(root: &FsNode, min_days: i64) -> Vec<StaleFile> {
let mut files = Vec::new();
root.flatten_files(&mut files);
let mut out: Vec<StaleFile> = files.into_iter()
.filter_map(|f| {
let m = f.modified?;
let days = age_days(m);
if days >= min_days {
Some(StaleFile { path: f.path.clone(), size: f.size, days_since_access: days })
} else {
None
}
})
.collect();
out.sort_by(|a, b| b.days_since_access.cmp(&a.days_since_access));
out
}
pub fn zero_byte_files(root: &FsNode) -> Vec<PathBuf> {
let mut files = Vec::new();
root.flatten_files(&mut files);
files.into_iter().filter(|f| f.size == 0 && f.apparent_size == 0).map(|f| f.path.clone()).collect()
}
pub fn empty_dirs(node: &FsNode, out: &mut Vec<PathBuf>) {
if !node.is_dir { return; }
if node.children.is_empty() {
out.push(node.path.clone());
return;
}
for c in &node.children {
empty_dirs(c, out);
}
}