diff --git a/src/exa.rs b/src/exa.rs index 42bbf7f..5e9b209 100644 --- a/src/exa.rs +++ b/src/exa.rs @@ -12,7 +12,6 @@ use std::os::{args, set_exit_status}; use dir::Dir; use file::File; use options::Options; -use options::Error::*; pub mod column; pub mod dir; @@ -90,25 +89,9 @@ fn main() { match Options::getopts(args.tail()) { Ok(options) => exa(&options), - Err(Help(text)) => { - println!("{}", text); - set_exit_status(2); - }, - Err(InvalidOptions(e)) => { + Err(e) => { println!("{}", e); - set_exit_status(3); - }, - Err(Conflict(a, b)) => { - println!("Option --{} conflicts with option {}", a, b); - set_exit_status(3); - }, - Err(Useless(a, false, b)) => { - println!("Option --{} is useless without option --{}", a, b); - set_exit_status(3); - }, - Err(Useless(a, true, b)) => { - println!("Option --{} is useless given option --{}", a, b); - set_exit_status(3); + set_exit_status(e.error_code()); }, }; } diff --git a/src/file.rs b/src/file.rs index 6f19819..d25a781 100644 --- a/src/file.rs +++ b/src/file.rs @@ -56,7 +56,7 @@ impl<'a> File<'a> { // The extension is the series of characters after a dot at // the end of a filename. This deliberately also counts // dotfiles - the ".git" folder has the extension "git". - name.rfind('.').map(|pos| name.slice_from(pos + 1).to_string()) + name.rfind('.').map(|p| name[p+1..].to_string()) } pub fn is_dotfile(&self) -> bool { diff --git a/src/options.rs b/src/options.rs index b81087a..2235db1 100644 --- a/src/options.rs +++ b/src/options.rs @@ -9,8 +9,11 @@ use term::dimensions; use std::ascii::AsciiExt; use std::slice::Iter; +use std::fmt; -#[derive(PartialEq, Show)] +use self::Error::*; + +#[derive(PartialEq, Debug)] pub enum SortField { Unsorted, Name, Extension, Size, FileInode } @@ -34,7 +37,7 @@ fn no_sort_field(field: &str) -> Error { Error::InvalidOptions(getopts::Fail::UnrecognizedOption(format!("--sort {}", field))) } -#[derive(PartialEq, Show)] +#[derive(PartialEq, Debug)] pub struct Options { pub list_dirs: bool, pub path_strs: Vec, @@ -44,7 +47,7 @@ pub struct Options { pub view: View, } -#[derive(PartialEq, Show)] +#[derive(PartialEq, Debug)] pub enum Error { InvalidOptions(getopts::Fail), Help(String), @@ -52,6 +55,25 @@ pub enum Error { Useless(&'static str, bool, &'static str), } +impl Error { + pub fn error_code(&self) -> isize { + if let Help(_) = *self { 2 } + else { 3 } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + InvalidOptions(ref e) => write!(f, "{}", e), + Help(ref text) => write!(f, "{}", text), + Conflict(a, b) => write!(f, "Option --{} conflicts with option {}", a, b), + Useless(a, false, b) => write!(f, "Option --{} is useless without option --{}", a, b), + Useless(a, true, b) => write!(f, "Option --{} is useless given option --{}", a, b), + } + } +} + impl Options { pub fn getopts(args: &[String]) -> Result { let opts = &[ @@ -215,6 +237,8 @@ mod test { use super::Error; use super::Error::*; + use std::fmt; + fn is_helpful(error: Result) -> bool { match error { Err(Help(_)) => true, @@ -222,6 +246,12 @@ mod test { } } + impl fmt::Display for Options { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } + } + #[test] fn help() { let opts = Options::getopts(&[ "--help".to_string() ]); @@ -275,6 +305,4 @@ mod test { let opts = Options::getopts(&[ "--oneline".to_string(), "--across".to_string() ]); assert_eq!(opts.unwrap_err(), Error::Useless("across", true, "oneline")) } - - }