summaryrefslogtreecommitdiffstats
path: root/src/files.rs
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-01-25 20:20:34 +0100
committerrabite <rabite@posteo.de>2019-01-25 20:20:34 +0100
commitc381203bb2c9fd91add74154237dcc93853f73c3 (patch)
tree0a5ce0a1f6a3f8130fe4782600c444f07734b1b1 /src/files.rs
parentf3f783a3a0bc3c96e4678c7fa986dc31bcb8d585 (diff)
sorting by name and size
Diffstat (limited to 'src/files.rs')
-rw-r--r--src/files.rs106
1 files changed, 79 insertions, 27 deletions
diff --git a/src/files.rs b/src/files.rs
index 1192659..ba37e04 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -4,27 +4,22 @@ use std::path::PathBuf;
use std::ffi::OsStr;
use std::cmp::{Ord, Ordering};
-pub struct Files(Vec<File>);
use lscolors::{LsColors, Style};
-impl Index<usize> for Files {
- type Output = File;
- fn index(&self, pos: usize) -> &Self::Output {
- &self.0[pos]
- }
lazy_static! {
static ref COLORS: LsColors = LsColors::from_env().unwrap();
}
-impl PartialOrd for File {
- fn partial_cmp(&self, other: &File) -> Option<Ordering> {
- Some(alphanumeric_sort::compare_str(&self.name, &other.name))
- }
+#[derive(PartialEq)]
+pub struct Files {
+ pub files: Vec<File>,
+ pub sort: SortBy,
}
-impl Ord for File {
- fn cmp(&self, other: &File) -> Ordering {
- alphanumeric_sort::compare_str(&self.name, &other.name)
+impl Index<usize> for Files {
+ type Output = File;
+ fn index(&self, pos: usize) -> &Self::Output {
+ &self.files[pos]
}
}
@@ -41,7 +36,7 @@ impl Files {
-> Result<Files, Box<dyn Error>>
where S: std::convert::AsRef<std::path::Path> {
let mut files = Vec::new();
- let mut dirs = Vec::new();
+
for file in std::fs::read_dir(path)? {
let file = file?;
let name = file.file_name();
@@ -56,26 +51,58 @@ impl Files {
None => None
};
let file = File::new(&name, path, kind, size as usize, style);
- match kind {
- Kind::Directory => dirs.push(file),
- _ => files.push(file),
- }
+ files.push(file)
}
+
+ let mut files = Files { files: files,
+ sort: SortBy::Name };
+
files.sort();
- dirs.sort();
- dirs.append(&mut files);
-
- let files = dirs;
-
- Ok(Files(files))
+ Ok(files)
+ }
+
+ pub fn sort(&mut self) {
+ match self.sort {
+ SortBy::Name => {
+ self.files.sort_by(|a,b| {
+ alphanumeric_sort::compare_str(&a.name, &b.name)
+ })
+ },
+ SortBy::Size => {
+ self.files.sort_by(|a,b| {
+ if a.size == b.size {
+ return alphanumeric_sort::compare_str(&b.name, &a.name)
+ }
+ a.size.cmp(&b.size).reverse()
+ });
+ },
+ _ => {}
+ };
+
+ // Direcories first
+ self.files.sort_by(|a,b| {
+ if a.is_dir() && !b.is_dir() {
+ Ordering::Less
+ } else { Ordering::Equal }
+ });
+ }
+
+ pub fn cycle_sort(&mut self) -> SortBy {
+ self.sort = match self.sort {
+ SortBy::Name => SortBy::Size,
+ SortBy::Size => SortBy::Name,
+ _ => { SortBy::Name }
+ };
+ self.sort();
+ self.sort
}
pub fn iter(&self) -> std::slice::Iter<File> {
- self.0.iter()
+ self.files.iter()
}
pub fn len(&self) -> usize {
- self.0.len()
+ self.files.len()
}
}
@@ -87,7 +114,28 @@ pub enum Kind {
Pipe
}
-#[derive(Debug, PartialEq, Eq)]
+impl std::fmt::Display for SortBy {
+ fn fmt(&self, formatter: &mut std::fmt::Formatter<'_> )
+ -> Result<(), std::fmt::Error> {
+ let text = match self {
+ SortBy::Name => "name",
+ SortBy::Size => "size",
+ SortBy::MDate => "mdate",
+ SortBy::CDate => "cdate"
+ };
+ write!(formatter, "{}", text)
+ }
+}
+
+#[derive(Debug,Copy,Clone,PartialEq)]
+pub enum SortBy {
+ Name,
+ Size,
+ MDate,
+ CDate
+}
+
+#[derive(Debug, PartialEq, Clone)]
pub struct File {
pub name: String,
pub path: PathBuf,
@@ -143,6 +191,10 @@ impl File {
Some(self.path.parent()?.parent()?.to_path_buf())
}
+ pub fn is_dir(&self) -> bool {
+ self.kind == Kind::Directory
+ }
+
pub fn path(&self) -> PathBuf {
self.path.clone()
}