diff options
Diffstat (limited to 'src/config/clean/app/display/sort_type.rs')
-rw-r--r-- | src/config/clean/app/display/sort_type.rs | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/config/clean/app/display/sort_type.rs b/src/config/clean/app/display/sort_type.rs new file mode 100644 index 0000000..3041951 --- /dev/null +++ b/src/config/clean/app/display/sort_type.rs @@ -0,0 +1,161 @@ +use std::cmp; +use std::collections::VecDeque; +use std::fs; +use std::time; + +use serde::Deserialize; + +use crate::fs::JoshutoDirEntry; + +use super::sort::SortOption; + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq)] +pub enum SortType { + Lexical, + Mtime, + Natural, + Size, + Ext, +} + +impl SortType { + pub fn from_str(s: &str) -> Option<Self> { + match s { + "lexical" => Some(SortType::Lexical), + "mtime" => Some(SortType::Mtime), + "natural" => Some(SortType::Natural), + "size" => Some(SortType::Size), + "ext" => Some(SortType::Ext), + _ => None, + } + } + pub const fn as_str(&self) -> &str { + match *self { + SortType::Lexical => "lexical", + SortType::Mtime => "mtime", + SortType::Natural => "natural", + SortType::Size => "size", + SortType::Ext => "ext", + } + } + pub fn cmp( + &self, + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, + ) -> cmp::Ordering { + match &self { + SortType::Natural => natural_sort(f1, f2, sort_option), + SortType::Lexical => lexical_sort(f1, f2, sort_option), + SortType::Size => size_sort(f1, f2), + SortType::Mtime => mtime_sort(f1, f2), + SortType::Ext => ext_sort(f1, f2), + } + } +} + +impl std::fmt::Display for SortType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +#[derive(Clone, Debug)] +pub struct SortTypes { + pub list: VecDeque<SortType>, +} + +impl SortTypes { + pub fn reorganize(&mut self, st: SortType) { + self.list.push_front(st); + self.list.pop_back(); + } + + pub fn cmp( + &self, + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, + ) -> cmp::Ordering { + for st in &self.list { + let res = st.cmp(f1, f2, sort_option); + if res != cmp::Ordering::Equal { + return res; + } + } + cmp::Ordering::Equal + } +} + +impl std::default::Default for SortTypes { + fn default() -> Self { + let list: VecDeque<SortType> = vec![ + SortType::Natural, + SortType::Lexical, + SortType::Size, + SortType::Ext, + SortType::Mtime, + ] + .into_iter() + .collect(); + + Self { list } + } +} + +fn mtime_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering { + fn compare( + file1: &JoshutoDirEntry, + file2: &JoshutoDirEntry, + ) -> Result<cmp::Ordering, std::io::Error> { + let f1_meta: fs::Metadata = std::fs::metadata(file1.file_path())?; + let f2_meta: fs::Metadata = std::fs::metadata(file2.file_path())?; + + let f1_mtime: time::SystemTime = f1_meta.modified()?; + let f2_mtime: time::SystemTime = f2_meta.modified()?; + Ok(f1_mtime.cmp(&f2_mtime)) + } + compare(file1, file2).unwrap_or(cmp::Ordering::Equal) +} + +fn size_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering { + file1.metadata.len().cmp(&file2.metadata.len()) +} + +fn ext_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering { + let f1_ext = file1.get_ext(); + let f2_ext = file2.get_ext(); + alphanumeric_sort::compare_str(f1_ext, f2_ext) +} + +fn lexical_sort( + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, +) -> cmp::Ordering { + let f1_name = f1.file_name(); + let f2_name = f2.file_name(); + if sort_option.case_sensitive { + f1_name.cmp(f2_name) + } else { + let f1_name = f1_name.to_lowercase(); + let f2_name = f2_name.to_lowercase(); + f1_name.cmp(&f2_name) + } +} + +fn natural_sort( + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, +) -> cmp::Ordering { + let f1_name = f1.file_name(); + let f2_name = f2.file_name(); + if sort_option.case_sensitive { + alphanumeric_sort::compare_str(f1_name, f2_name) + } else { + let f1_name = f1_name.to_lowercase(); + let f2_name = f2_name.to_lowercase(); + alphanumeric_sort::compare_str(f1_name, f2_name) + } +} |