Skip to main content

tree_rust/
sort.rs

1use crate::tree::TreeEntry;
2
3/// Sort key options
4#[derive(Debug, Clone, Default)]
5pub enum SortKey {
6    #[default]
7    Name,
8    Size,
9    Time,
10    None,
11}
12
13impl SortKey {
14    pub fn from_str(s: &str) -> Self {
15        match s.to_lowercase().as_str() {
16            "name" => SortKey::Name,
17            "size" => SortKey::Size,
18            "mtime" | "time" => SortKey::Time,
19            "none" => SortKey::None,
20            _ => SortKey::Name,
21        }
22    }
23}
24
25/// Sorter for tree entries
26pub struct Sorter {
27    key: SortKey,
28    reverse: bool,
29    dirs_first: bool,
30}
31
32impl Sorter {
33    pub fn new(key: SortKey, reverse: bool, dirs_first: bool) -> Self {
34        Self {
35            key,
36            reverse,
37            dirs_first,
38        }
39    }
40
41    pub fn sort(&self, entries: &mut [TreeEntry]) {
42        if matches!(self.key, SortKey::None) && !self.dirs_first {
43            return;
44        }
45
46        entries.sort_by(|a, b| {
47            // Dirs first handling
48            if self.dirs_first {
49                match (a.is_dir, b.is_dir) {
50                    (true, false) => return std::cmp::Ordering::Less,
51                    (false, true) => return std::cmp::Ordering::Greater,
52                    _ => {}
53                }
54            }
55
56            let ordering = match self.key {
57                SortKey::Name => a.name.to_lowercase().cmp(&b.name.to_lowercase()),
58                SortKey::Size => a.size().cmp(&b.size()),
59                SortKey::Time => {
60                    let a_time = a.modified();
61                    let b_time = b.modified();
62                    match (a_time, b_time) {
63                        (Some(at), Some(bt)) => at.cmp(&bt),
64                        (Some(_), None) => std::cmp::Ordering::Less,
65                        (None, Some(_)) => std::cmp::Ordering::Greater,
66                        (None, None) => std::cmp::Ordering::Equal,
67                    }
68                }
69                SortKey::None => std::cmp::Ordering::Equal,
70            };
71
72            if self.reverse {
73                ordering.reverse()
74            } else {
75                ordering
76            }
77        });
78    }
79}