swdir/helpers/
dir_node.rs1use std::{cmp::Ordering, path::PathBuf};
2
3#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
4pub struct DirNode {
6 pub path: PathBuf,
7 pub sub_dirs: Vec<DirNode>, pub files: Vec<PathBuf>, }
10
11impl DirNode {
12 pub fn with_path<T: Into<PathBuf>>(path: T) -> Self {
14 Self {
15 path: path.into(),
16 sub_dirs: vec![],
17 files: vec![],
18 }
19 }
20
21 pub fn flatten_paths(&self) -> Vec<PathBuf> {
23 let mut ret = self.files.clone();
24 ret.extend(
25 self.sub_dirs
26 .iter()
27 .flat_map(|dir_node| dir_node.flatten_paths()),
28 );
29 ret.sort_by(flatten_paths_sort);
31 ret
32 }
33}
34
35fn flatten_paths_sort(a: &PathBuf, b: &PathBuf) -> Ordering {
37 let depth_a = a.components().count();
39 let depth_b = b.components().count();
40
41 depth_a
42 .cmp(&depth_b)
43 .then_with(|| {
44 let is_likely_dir_a = a.extension().is_none();
47 let is_likely_dir_b = b.extension().is_none();
48
49 is_likely_dir_b.cmp(&is_likely_dir_a)
51 })
52 .then_with(|| {
53 let name_a = a.file_name().unwrap_or_default();
55 let name_b = b.file_name().unwrap_or_default();
56 name_a.cmp(name_b)
57 })
58}