use std::{
cmp::Ordering,
path::{Path, PathBuf},
};
pub mod dir_node_count;
use dir_node_count::DirNodeCount;
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct DirNode {
pub path: PathBuf,
pub sub_dirs: Vec<DirNode>, pub files: Vec<PathBuf>, }
impl DirNode {
pub fn with_path<T: Into<PathBuf>>(path: T) -> Self {
Self {
path: path.into(),
sub_dirs: vec![],
files: vec![],
}
}
pub fn flatten_paths(&self) -> Vec<PathBuf> {
let mut ret = self.files.clone();
ret.extend(
self.sub_dirs
.iter()
.flat_map(|dir_node| dir_node.flatten_paths()),
);
ret.sort_by(|a, b| flatten_paths_sort(a, b));
ret
}
pub fn count(&self) -> DirNodeCount {
DirNodeCount::new(self)
}
}
fn flatten_paths_sort(a: &Path, b: &Path) -> Ordering {
let depth_a = a.components().count();
let depth_b = b.components().count();
depth_a
.cmp(&depth_b)
.then_with(|| {
let is_likely_dir_a = a.extension().is_none();
let is_likely_dir_b = b.extension().is_none();
is_likely_dir_b.cmp(&is_likely_dir_a)
})
.then_with(|| {
let name_a = a.file_name().unwrap_or_default();
let name_b = b.file_name().unwrap_or_default();
name_a.cmp(name_b)
})
}