use crate::path::FileEntry;
use serde::{self, Deserialize, Serialize};
use std::fmt;
use termtree::Tree;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FileSortMethod {
NameAsc,
NameDesc,
DateAsc,
DateDesc,
}
impl fmt::Display for FileSortMethod {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FileSortMethod::NameAsc => write!(f, "Name (A → Z)"),
FileSortMethod::NameDesc => write!(f, "Name (Z → A)"),
FileSortMethod::DateAsc => write!(f, "Date (Old → New)"),
FileSortMethod::DateDesc => write!(f, "Date (New → Old)"),
}
}
}
pub fn sort_files(files: &mut [FileEntry], sort_method: Option<FileSortMethod>) {
if let Some(method) = sort_method {
match method {
FileSortMethod::NameAsc => {
files.sort_by(|a, b| a.path.cmp(&b.path));
}
FileSortMethod::NameDesc => {
files.sort_by(|a, b| b.path.cmp(&a.path));
}
FileSortMethod::DateAsc => {
files.sort_by_key(|f| f.mod_time.unwrap_or(0));
}
FileSortMethod::DateDesc => {
files.sort_by_key(|f| std::cmp::Reverse(f.mod_time.unwrap_or(0)));
}
}
}
}
pub fn sort_tree<D: Ord + std::fmt::Display>(
tree: &mut Tree<D>,
sort_method: Option<FileSortMethod>,
) {
if let Some(method) = sort_method {
let ascending = match method {
FileSortMethod::NameAsc | FileSortMethod::DateAsc => true,
FileSortMethod::NameDesc | FileSortMethod::DateDesc => false,
};
sort_tree_impl(tree, ascending);
}
}
fn sort_tree_impl<D: Ord + std::fmt::Display>(tree: &mut Tree<D>, ascending: bool) {
tree.leaves.sort_by(|a, b| {
if ascending {
a.root.cmp(&b.root)
} else {
b.root.cmp(&a.root)
}
});
for leaf in &mut tree.leaves {
sort_tree_impl(leaf, ascending);
}
}