1use crate::scanner::FsNode;
2use serde::Serialize;
3use std::path::PathBuf;
4
5#[derive(Debug, Clone, Serialize)]
6pub struct SizeEntry {
7 pub path: PathBuf,
8 pub size: u64,
9 pub is_dir: bool,
10}
11
12pub fn top_files(root: &FsNode, min_size: u64, limit: usize) -> Vec<SizeEntry> {
13 let mut files = Vec::new();
14 root.flatten_files(&mut files);
15 let mut entries: Vec<SizeEntry> = files.into_iter()
16 .filter(|f| f.size >= min_size)
17 .map(|f| SizeEntry { path: f.path.clone(), size: f.size, is_dir: false })
18 .collect();
19 entries.sort_by(|a, b| b.size.cmp(&a.size));
20 entries.truncate(limit);
21 entries
22}
23
24pub fn top_dirs(root: &FsNode, limit: usize) -> Vec<SizeEntry> {
25 let mut out = Vec::new();
26 collect_dirs(root, &mut out);
27 out.sort_by(|a, b| b.size.cmp(&a.size));
28 out.truncate(limit);
29 out
30}
31
32fn collect_dirs(node: &FsNode, out: &mut Vec<SizeEntry>) {
33 if !node.is_dir { return; }
34 out.push(SizeEntry { path: node.path.clone(), size: node.size, is_dir: true });
35 for c in &node.children {
36 if c.is_dir { collect_dirs(c, out); }
37 }
38}
39
40pub fn type_breakdown(root: &FsNode) -> Vec<(String, u64, u64)> {
41 let mut files = Vec::new();
42 root.flatten_files(&mut files);
43 use std::collections::HashMap;
44 let mut groups: HashMap<&'static str, (u64, u64)> = HashMap::new();
45 for f in files {
46 let ext = f.path.extension().and_then(|e| e.to_str()).unwrap_or("").to_lowercase();
47 let cat = categorize_ext(&ext);
48 let entry = groups.entry(cat).or_insert((0, 0));
49 entry.0 += f.size;
50 entry.1 += 1;
51 }
52 let mut result: Vec<(String, u64, u64)> = groups.into_iter().map(|(k, (s, c))| (k.to_string(), s, c)).collect();
53 result.sort_by(|a, b| b.1.cmp(&a.1));
54 result
55}
56
57fn categorize_ext(ext: &str) -> &'static str {
58 match ext {
59 "mp4" | "mkv" | "avi" | "mov" | "webm" | "flv" => "video",
60 "jpg" | "jpeg" | "png" | "gif" | "webp" | "bmp" | "svg" | "raw" => "image",
61 "mp3" | "wav" | "flac" | "ogg" | "m4a" => "audio",
62 "zip" | "tar" | "gz" | "xz" | "7z" | "rar" | "bz2" | "zst" => "archive",
63 "iso" | "img" | "appimage" | "deb" | "rpm" => "package",
64 "pdf" | "doc" | "docx" | "xls" | "xlsx" | "ppt" | "pptx" | "odt" => "document",
65 "log" => "log",
66 "so" | "dll" | "bin" | "exe" | "o" | "a" => "binary",
67 "" => "no-extension",
68 _ => "other",
69 }
70}