diff --git a/src/filter.rs b/src/filter.rs index ed20c9e..73fbd6a 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -1,9 +1,7 @@ use crate::display_node::DisplayNode; use crate::node::Node; use std::collections::BinaryHeap; -use std::collections::HashMap; use std::collections::HashSet; -use std::ffi::OsStr; use std::path::Path; use std::path::PathBuf; @@ -39,62 +37,6 @@ pub fn get_biggest( recursive_rebuilder(&allowed_nodes, &root) } -#[derive(PartialEq, Eq, PartialOrd, Ord)] -struct ExtensionNode<'a> { - size: u64, - extension: Option<&'a OsStr>, -} - -pub fn get_all_file_types(top_level_nodes: &[Node], n: usize) -> Option { - let ext_nodes = { - let mut extension_cumulative_sizes = HashMap::new(); - build_by_all_file_types(top_level_nodes, &mut extension_cumulative_sizes); - - let mut extension_cumulative_sizes: Vec> = extension_cumulative_sizes - .iter() - .map(|(&extension, &size)| ExtensionNode { extension, size }) - .collect(); - - extension_cumulative_sizes.sort_by(|lhs, rhs| lhs.cmp(rhs).reverse()); - - extension_cumulative_sizes - }; - - let mut ext_nodes_iter = ext_nodes.iter(); - - // First, collect the first N - 1 nodes... - let mut displayed: Vec = ext_nodes_iter - .by_ref() - .take(if n > 1 { n - 1 } else { 1 }) - .map(|node| DisplayNode { - name: PathBuf::from( - node.extension - .map(|ext| format!(".{}", ext.to_string_lossy())) - .unwrap_or_else(|| "(no extension)".to_owned()), - ), - size: node.size, - children: vec![], - }) - .collect(); - - // ...then, aggregate the remaining nodes (if any) into a single "(others)" node - if ext_nodes_iter.len() > 0 { - displayed.push(DisplayNode { - name: PathBuf::from("(others)"), - size: ext_nodes_iter.map(|node| node.size).sum(), - children: vec![], - }); - } - - let result = DisplayNode { - name: PathBuf::from("(total)"), - size: displayed.iter().map(|node| node.size).sum(), - children: displayed, - }; - - Some(result) -} - fn add_children<'a>( using_a_filter: bool, file_or_folder: &'a Node, @@ -112,20 +54,6 @@ fn add_children<'a>( heap } -fn build_by_all_file_types<'a>( - top_level_nodes: &'a [Node], - counter: &mut HashMap, u64>, -) { - for node in top_level_nodes { - if node.name.is_file() { - let ext = node.name.extension(); - let cumulative_size = counter.entry(ext).or_default(); - *cumulative_size += node.size; - } - build_by_all_file_types(&node.children, counter) - } -} - fn get_new_root(top_level_nodes: Vec) -> Node { if top_level_nodes.len() != 1 { Node { diff --git a/src/filter_type.rs b/src/filter_type.rs new file mode 100644 index 0000000..974d9c3 --- /dev/null +++ b/src/filter_type.rs @@ -0,0 +1,75 @@ +use crate::display_node::DisplayNode; +use crate::node::Node; +use std::collections::HashMap; +use std::ffi::OsStr; +use std::path::PathBuf; + +#[derive(PartialEq, Eq, PartialOrd, Ord)] +struct ExtensionNode<'a> { + size: u64, + extension: Option<&'a OsStr>, +} + +pub fn get_all_file_types(top_level_nodes: &[Node], n: usize) -> Option { + let ext_nodes = { + let mut extension_cumulative_sizes = HashMap::new(); + build_by_all_file_types(top_level_nodes, &mut extension_cumulative_sizes); + + let mut extension_cumulative_sizes: Vec> = extension_cumulative_sizes + .iter() + .map(|(&extension, &size)| ExtensionNode { extension, size }) + .collect(); + + extension_cumulative_sizes.sort_by(|lhs, rhs| lhs.cmp(rhs).reverse()); + + extension_cumulative_sizes + }; + + let mut ext_nodes_iter = ext_nodes.iter(); + + // First, collect the first N - 1 nodes... + let mut displayed: Vec = ext_nodes_iter + .by_ref() + .take(if n > 1 { n - 1 } else { 1 }) + .map(|node| DisplayNode { + name: PathBuf::from( + node.extension + .map(|ext| format!(".{}", ext.to_string_lossy())) + .unwrap_or_else(|| "(no extension)".to_owned()), + ), + size: node.size, + children: vec![], + }) + .collect(); + + // ...then, aggregate the remaining nodes (if any) into a single "(others)" node + if ext_nodes_iter.len() > 0 { + displayed.push(DisplayNode { + name: PathBuf::from("(others)"), + size: ext_nodes_iter.map(|node| node.size).sum(), + children: vec![], + }); + } + + let result = DisplayNode { + name: PathBuf::from("(total)"), + size: displayed.iter().map(|node| node.size).sum(), + children: displayed, + }; + + Some(result) +} + +fn build_by_all_file_types<'a>( + top_level_nodes: &'a [Node], + counter: &mut HashMap, u64>, +) { + for node in top_level_nodes { + if node.name.is_file() { + let ext = node.name.extension(); + let cumulative_size = counter.entry(ext).or_default(); + *cumulative_size += node.size; + } + build_by_all_file_types(&node.children, counter) + } +} diff --git a/src/main.rs b/src/main.rs index 357e313..3e8a135 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,8 @@ use self::display::draw_it; use clap::{crate_version, Arg}; use clap::{Command, Values}; use dir_walker::{walk_it, WalkData}; -use filter::{get_all_file_types, get_biggest}; +use filter::get_biggest; +use filter_type::get_all_file_types; use regex::Regex; use std::cmp::max; use std::path::PathBuf; @@ -22,6 +23,7 @@ mod dir_walker; mod display; mod display_node; mod filter; +mod filter_type; mod node; mod platform; mod utils;