From cb1b8bc2d79f23aa979588505a3b70cc29f230df Mon Sep 17 00:00:00 2001 From: Ben S Date: Sat, 24 May 2014 02:17:43 +0100 Subject: [PATCH] Add sort option And move options struct into its own module --- exa.rs | 26 +++++++++++++------------- file.rs | 6 +++--- options.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 options.rs diff --git a/exa.rs b/exa.rs index f4374d2..ccb8719 100644 --- a/exa.rs +++ b/exa.rs @@ -8,16 +8,14 @@ use std::io::fs; use file::File; use column::defaultColumns; +use options::{Options, SortField, Name}; pub mod colours; pub mod column; pub mod format; pub mod file; pub mod unix; - -struct Options { - showInvisibles: bool, -} +pub mod options; fn main() { let args: Vec = os::args().iter() @@ -25,7 +23,8 @@ fn main() { .collect(); let opts = ~[ - getopts::optflag("a", "all", "show dot-files") + getopts::optflag("a", "all", "show dot-files"), + getopts::optopt("s", "sort", "field to sort by", "WORD"), ]; let matches = match getopts::getopts(args.tail(), opts) { @@ -34,7 +33,8 @@ fn main() { }; let opts = Options { - showInvisibles: matches.opt_present("all") + showInvisibles: matches.opt_present("all"), + sortField: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(Name), }; let strs = if matches.free.is_empty() { @@ -49,18 +49,18 @@ fn main() { } } -fn list(opts: Options, path: Path) { - let mut files = match fs::readdir(&path) { - Ok(files) => files, +fn list(options: Options, path: Path) { + let paths = match fs::readdir(&path) { + Ok(paths) => paths, Err(e) => fail!("readdir: {}", e), }; - files.sort_by(|a, b| a.filename_str().cmp(&b.filename_str())); + + let mut files = paths.iter().map(|path| File::from_path(path)).collect(); + options.sort(&mut files); let columns = defaultColumns(); - let table: Vec> = files.iter() - .map(|p| File::from_path(p)) - .filter(|f| !f.is_dotfile() || opts.showInvisibles ) + .filter(|&f| options.show(f)) .map(|f| columns.iter().map(|c| f.display(c)).collect()) .collect(); diff --git a/file.rs b/file.rs index 0e0fc4c..e0f11f5 100644 --- a/file.rs +++ b/file.rs @@ -10,9 +10,9 @@ use unix::{get_user_name, get_group_name}; // only to determine what kind of file it is, so carry the `stat` // result around with the file for safe keeping. pub struct File<'a> { - name: &'a str, - path: &'a Path, - stat: io::FileStat, + pub name: &'a str, + pub path: &'a Path, + pub stat: io::FileStat, } impl<'a> File<'a> { diff --git a/options.rs b/options.rs new file mode 100644 index 0000000..d1ecfd9 --- /dev/null +++ b/options.rs @@ -0,0 +1,41 @@ +use file::File; + +pub enum SortField { + Name, Size +} + +pub struct Options { + pub showInvisibles: bool, + pub sortField: SortField, +} + +impl SortField { + pub fn from_word(word: StrBuf) -> SortField { + match word.as_slice() { + "name" => Name, + "size" => Size, + _ => fail!("Invalid sorting order"), + } + } + + fn sort(&self, files: &mut Vec) { + match *self { + Name => files.sort_by(|a, b| a.name.cmp(&b.name)), + Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)), + } + } +} + +impl Options { + pub fn sort(&self, files: &mut Vec) { + self.sortField.sort(files); + } + + pub fn show(&self, f: &File) -> bool { + if self.showInvisibles { + true + } else { + !f.name.starts_with(".") + } + } +}