2017-07-26 16:48:18 +00:00
|
|
|
|
use std::ffi::{OsStr, OsString};
|
2016-04-17 19:38:37 +00:00
|
|
|
|
use std::fmt;
|
|
|
|
|
use std::num::ParseIntError;
|
|
|
|
|
|
2016-10-30 14:43:33 +00:00
|
|
|
|
use glob;
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
2017-06-23 21:50:29 +00:00
|
|
|
|
use options::help::HelpString;
|
2017-07-26 16:48:18 +00:00
|
|
|
|
use options::parser::{Arg, ParseError};
|
2017-06-23 21:50:29 +00:00
|
|
|
|
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
2016-08-29 01:56:32 +00:00
|
|
|
|
/// A list of legal choices for an argument-taking option
|
|
|
|
|
#[derive(PartialEq, Debug)]
|
2017-06-23 21:58:07 +00:00
|
|
|
|
pub struct Choices(&'static [&'static str]);
|
2016-08-29 01:56:32 +00:00
|
|
|
|
|
|
|
|
|
impl fmt::Display for Choices {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-07-26 16:48:18 +00:00
|
|
|
|
write!(f, "(choices: {})", self.0.join(", "))
|
2016-08-29 01:56:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-17 19:38:37 +00:00
|
|
|
|
/// A **misfire** is a thing that can happen instead of listing files -- a
|
|
|
|
|
/// catch-all for anything outside the program’s normal execution.
|
|
|
|
|
#[derive(PartialEq, Debug)]
|
|
|
|
|
pub enum Misfire {
|
|
|
|
|
|
2017-07-26 16:48:18 +00:00
|
|
|
|
/// The getopts crate didn’t like these Arguments.
|
|
|
|
|
InvalidOptions(ParseError),
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
2017-07-26 16:48:18 +00:00
|
|
|
|
/// The user supplied an illegal choice to an Argument.
|
|
|
|
|
BadArgument(&'static Arg, OsString, Choices),
|
2016-08-29 01:56:32 +00:00
|
|
|
|
|
2016-04-17 19:38:37 +00:00
|
|
|
|
/// The user asked for help. This isn’t strictly an error, which is why
|
|
|
|
|
/// this enum isn’t named Error!
|
2017-06-23 21:50:29 +00:00
|
|
|
|
Help(HelpString),
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
|
|
|
|
/// The user wanted the version number.
|
|
|
|
|
Version,
|
|
|
|
|
|
|
|
|
|
/// Two options were given that conflict with one another.
|
2017-07-26 16:48:18 +00:00
|
|
|
|
Conflict(&'static Arg, &'static Arg),
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
|
|
|
|
/// An option was given that does nothing when another one either is or
|
|
|
|
|
/// isn't present.
|
2017-07-26 16:48:18 +00:00
|
|
|
|
Useless(&'static Arg, bool, &'static Arg),
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
|
|
|
|
/// An option was given that does nothing when either of two other options
|
|
|
|
|
/// are not present.
|
2017-07-26 16:48:18 +00:00
|
|
|
|
Useless2(&'static Arg, &'static Arg, &'static Arg),
|
|
|
|
|
|
|
|
|
|
/// A very specific edge case where --tree can’t be used with --all twice.
|
|
|
|
|
TreeAllAll,
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
|
|
|
|
/// A numeric option was given that failed to be parsed as a number.
|
|
|
|
|
FailedParse(ParseIntError),
|
2016-10-30 14:43:33 +00:00
|
|
|
|
|
|
|
|
|
/// A glob ignore was given that failed to be parsed as a pattern.
|
|
|
|
|
FailedGlobPattern(String),
|
2016-04-17 19:38:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Misfire {
|
|
|
|
|
|
|
|
|
|
/// The OS return code this misfire should signify.
|
2017-06-23 21:12:21 +00:00
|
|
|
|
pub fn is_error(&self) -> bool {
|
2017-05-17 20:01:12 +00:00
|
|
|
|
match *self {
|
2017-06-23 21:12:21 +00:00
|
|
|
|
Misfire::Help(_) => false,
|
|
|
|
|
Misfire::Version => false,
|
|
|
|
|
_ => true,
|
2017-05-17 20:01:12 +00:00
|
|
|
|
}
|
2016-04-17 19:38:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The Misfire that happens when an option gets given the wrong
|
|
|
|
|
/// argument. This has to use one of the `getopts` failure
|
|
|
|
|
/// variants--it’s meant to take just an option name, rather than an
|
|
|
|
|
/// option *and* an argument, but it works just as well.
|
2017-07-26 16:48:18 +00:00
|
|
|
|
pub fn bad_argument(option: &'static Arg, otherwise: &OsStr, legal: &'static [&'static str]) -> Misfire {
|
|
|
|
|
Misfire::BadArgument(option, otherwise.to_os_string(), Choices(legal))
|
2016-04-17 19:38:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-30 14:43:33 +00:00
|
|
|
|
impl From<glob::PatternError> for Misfire {
|
|
|
|
|
fn from(error: glob::PatternError) -> Misfire {
|
|
|
|
|
Misfire::FailedGlobPattern(error.to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-17 19:38:37 +00:00
|
|
|
|
impl fmt::Display for Misfire {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
use self::Misfire::*;
|
|
|
|
|
|
|
|
|
|
match *self {
|
2017-07-26 16:48:18 +00:00
|
|
|
|
BadArgument(ref a, ref b, ref c) => write!(f, "Option {} has no value {:?} (Choices: {})", a, b, c),
|
|
|
|
|
InvalidOptions(ref e) => write!(f, "{:?}", e),
|
|
|
|
|
Help(ref text) => write!(f, "{}", text),
|
|
|
|
|
Version => write!(f, "exa {}", env!("CARGO_PKG_VERSION")),
|
|
|
|
|
Conflict(ref a, ref b) => write!(f, "Option {} conflicts with option {}.", a, b),
|
|
|
|
|
Useless(ref a, false, ref b) => write!(f, "Option {} is useless without option {}.", a, b),
|
|
|
|
|
Useless(ref a, true, ref b) => write!(f, "Option {} is useless given option {}.", a, b),
|
|
|
|
|
Useless2(ref a, ref b1, ref b2) => write!(f, "Option {} is useless without options {} or {}.", a, b1, b2),
|
|
|
|
|
TreeAllAll => write!(f, "Option --tree is useless given --all --all."),
|
|
|
|
|
FailedParse(ref e) => write!(f, "Failed to parse number: {}", e),
|
|
|
|
|
FailedGlobPattern(ref e) => write!(f, "Failed to parse glob pattern: {}", e),
|
2016-04-17 19:38:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|