2015-09-09 02:38:44 +00:00
|
|
|
use std::process;
|
2015-09-05 21:17:32 +00:00
|
|
|
use std::error::Error;
|
2015-10-30 03:49:39 +00:00
|
|
|
use std::fmt as std_fmt;
|
|
|
|
use std::io::{self, Write};
|
|
|
|
use std::convert::From;
|
|
|
|
|
|
|
|
use fmt::Format;
|
|
|
|
|
|
|
|
pub type ClapResult<T> = Result<T, ClapError>;
|
2015-09-05 21:17:32 +00:00
|
|
|
|
2015-10-31 05:19:24 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
pub mod error_builder {
|
|
|
|
use super::ClapError;
|
|
|
|
use super::ClapErrorType as cet;
|
|
|
|
use fmt::Format;
|
|
|
|
|
|
|
|
/// Error occurs when clap find two ore more conflicting arguments
|
|
|
|
pub fn ArgumentConflict<S>(arg: S, other: Option<S>, usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The argument '{}' cannot be used with {}\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(arg.as_ref()),
|
|
|
|
match other {
|
|
|
|
Some(name) => format!("'{}'", Format::Warning(name)),
|
|
|
|
None => "one or more of the other specified arguments".to_owned(),
|
|
|
|
},
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::ArgumentConflict,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when option does not allow empty values but some was found
|
|
|
|
pub fn EmptyValue<S>(arg: S, usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The argument '{}' requires a value but none was supplied\
|
|
|
|
\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(arg.as_ref()),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::InvalidValue,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when some possible values were set, but clap found unexpected value
|
|
|
|
pub fn InvalidValue<S>(bad_val: S,
|
|
|
|
arg: S,
|
|
|
|
valid_vals: S,
|
|
|
|
did_you_mean: S,
|
|
|
|
usage: S) -> ClapError where S: AsRef<str>
|
|
|
|
{
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} '{}' isn't a valid value for '{}'\n\t\
|
|
|
|
[valid values:{}]\n\
|
|
|
|
{}\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(bad_val.as_ref()),
|
|
|
|
Format::Warning(arg.as_ref()),
|
|
|
|
valid_vals.as_ref(),
|
|
|
|
did_you_mean.as_ref(),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::InvalidValue,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when clap found unexpected flag or option
|
|
|
|
pub fn InvalidArgument<S>(arg: S,
|
|
|
|
did_you_mean: Option<S>,
|
|
|
|
usage: S) -> ClapError where S: AsRef<str>
|
|
|
|
{
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The argument '{}' isn't valid{}\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(arg),
|
|
|
|
if did_you_mean.is_some() {
|
|
|
|
format!("{}\n", did_you_mean.unwrap().as_ref())
|
|
|
|
} else {
|
|
|
|
"".to_owned()
|
|
|
|
},
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::InvalidArgument,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when clap found unexpected subcommand
|
|
|
|
pub fn InvalidSubcommand<S>(subcmd: S,
|
|
|
|
did_you_mean: S,
|
|
|
|
name: S,
|
|
|
|
usage: S) -> ClapError where S: AsRef<str>
|
|
|
|
{
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The subcommand '{}' isn't valid\n\t\
|
|
|
|
Did you mean '{}' ?\n\n\
|
|
|
|
If you received this message in error, try \
|
|
|
|
re-running with '{} {} {}'\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(subcmd.as_ref()),
|
|
|
|
Format::Good(did_you_mean.as_ref()),
|
|
|
|
name.as_ref(),
|
|
|
|
Format::Good("--"),
|
|
|
|
subcmd.as_ref(),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::InvalidSubcommand,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when one or more required arguments missing
|
|
|
|
pub fn MissingRequiredArgument<S>(required: S, usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The following required arguments were not supplied:{}\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
required.as_ref(),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::MissingRequiredArgument,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when required subcommand missing
|
|
|
|
pub fn MissingSubcommand<S>(name: S, usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} '{}' requires a subcommand but none was provided\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(name),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::MissingSubcommand,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Error occurs when argument contains invalid unicode characters
|
|
|
|
pub fn InvalidUnicode<S>(usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} Invalid unicode character in one or more arguments\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::InvalidUnicode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when argument got more values then were expected
|
|
|
|
pub fn TooManyValues<S>(val: S, arg: S, usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The argument '{}' was found, but '{}' wasn't expecting \
|
|
|
|
any more values\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(val),
|
|
|
|
Format::Warning(arg),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::TooManyValues,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when argument got less values then were expected
|
|
|
|
pub fn TooFewValues<S>(arg: S,
|
|
|
|
min_vals: u8,
|
|
|
|
curr_vals: usize,
|
|
|
|
usage: S) -> ClapError where S: AsRef<str>
|
|
|
|
{
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The argument '{}' requires at least {} values, but {} w{} \
|
|
|
|
provided\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(arg.as_ref()),
|
|
|
|
Format::Warning(min_vals.to_string()),
|
|
|
|
Format::Warning(curr_vals.to_string()),
|
|
|
|
if curr_vals > 1 { "ere" } else { "as" },
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::TooFewValues,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Option fails validation of a custom validator
|
|
|
|
pub fn ValueValidationError<S>(err: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
err.as_ref()),
|
|
|
|
error_type: cet::ValueValidationError,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when argument got a different number of values then were expected
|
|
|
|
pub fn WrongNumValues<S>(arg: S,
|
|
|
|
num_vals: u8,
|
|
|
|
curr_vals: usize,
|
|
|
|
suffix: S,
|
|
|
|
usage: S) -> ClapError where S: AsRef<str>
|
|
|
|
{
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The argument '{}' requires {} values, but {} w{} \
|
|
|
|
provided\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(arg.as_ref()),
|
|
|
|
Format::Warning(num_vals.to_string()),
|
|
|
|
Format::Warning(curr_vals.to_string()),
|
|
|
|
suffix.as_ref(),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::InvalidSubcommand,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when clap find argument while is was not expecting any
|
|
|
|
pub fn UnexpectedArgument<S>(arg: S, name: S, usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} Found argument '{}', but {} wasn't expecting any\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(arg),
|
|
|
|
Format::Warning(name),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::UnexpectedArgument,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Error occurs when argument was used multiple times and was not set as multiple.
|
|
|
|
pub fn UnexpectedMultipleUsage<S>(arg: S, usage: S) -> ClapError where S: AsRef<str> {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} The argument '{}' was supplied more than once, but does \
|
|
|
|
not support multiple values\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
Format::Error("error:"),
|
|
|
|
Format::Warning(arg),
|
|
|
|
usage.as_ref(),
|
|
|
|
Format::Good("--help")),
|
|
|
|
error_type: cet::UnexpectedMultipleUsage,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Command line argument parser error types
|
2015-10-31 05:19:24 +00:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2015-09-04 21:32:11 +00:00
|
|
|
pub enum ClapErrorType {
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Error occurs when some possible values were set, but clap found unexpected value
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug").index(1)
|
|
|
|
/// .possible_value("fast")
|
|
|
|
/// .possible_value("slow"))
|
|
|
|
/// .get_matches_from_safe(vec!["", "other"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
InvalidValue,
|
|
|
|
/// Error occurs when clap found unexpected flag or option
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::from_usage("-f, --flag 'some flag'"))
|
|
|
|
/// .get_matches_from_safe(vec!["", "--other"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
InvalidArgument,
|
|
|
|
/// Error occurs when clap found unexpected subcommand
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg, SubCommand};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
2015-11-01 14:02:37 +00:00
|
|
|
/// .subcommand(SubCommand::with_name("config")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .about("Used for configuration")
|
|
|
|
/// .arg(Arg::with_name("config_file")
|
|
|
|
/// .help("The configuration file to use")
|
|
|
|
/// .index(1)))
|
|
|
|
/// .get_matches_from_safe(vec!["", "other"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
InvalidSubcommand,
|
|
|
|
/// Error occurs when option does not allow empty values but some was found
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug")
|
|
|
|
/// .empty_values(false))
|
|
|
|
/// .arg(Arg::with_name("color"))
|
|
|
|
/// .get_matches_from_safe(vec!["", "--debug", "--color"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
EmptyValue,
|
2015-10-05 00:09:12 +00:00
|
|
|
/// Option fails validation of a custom validator
|
|
|
|
ValueValidationError,
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Parser inner error
|
|
|
|
ArgumentError,
|
2015-10-05 00:09:12 +00:00
|
|
|
/// Error occurs when an application got more arguments then were expected
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug").index(1)
|
|
|
|
/// .max_values(2))
|
|
|
|
/// .get_matches_from_safe(vec!["", "too", "much", "values"]);
|
|
|
|
/// ```
|
|
|
|
TooManyArgs,
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Error occurs when argument got more values then were expected
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug").index(1)
|
|
|
|
/// .max_values(2))
|
|
|
|
/// .get_matches_from_safe(vec!["", "too", "much", "values"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-10-05 00:09:12 +00:00
|
|
|
TooManyValues,
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Error occurs when argument got less values then were expected
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug").index(1)
|
|
|
|
/// .min_values(3))
|
|
|
|
/// .get_matches_from_safe(vec!["", "too", "few"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
TooFewValues,
|
2015-10-05 00:09:12 +00:00
|
|
|
/// Error occurs when argument got a different number of values then were expected
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug").index(1)
|
|
|
|
/// .max_values(2))
|
|
|
|
/// .get_matches_from_safe(vec!["", "too", "much", "values"]);
|
|
|
|
/// ```
|
|
|
|
WrongNumValues,
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Error occurs when clap find two ore more conflicting arguments
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug")
|
|
|
|
/// .conflicts_with("color"))
|
|
|
|
/// .get_matches_from_safe(vec!["", "--debug", "--color"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
ArgumentConflict,
|
|
|
|
/// Error occurs when one or more required arguments missing
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug")
|
|
|
|
/// .required(true))
|
|
|
|
/// .get_matches_from_safe(vec![""]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
MissingRequiredArgument,
|
|
|
|
/// Error occurs when required subcommand missing
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg, AppSettings, SubCommand};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .setting(AppSettings::SubcommandRequired)
|
2015-11-01 14:02:37 +00:00
|
|
|
/// .subcommand(SubCommand::with_name("config")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .about("Used for configuration")
|
|
|
|
/// .arg(Arg::with_name("config_file")
|
|
|
|
/// .help("The configuration file to use")
|
|
|
|
/// .index(1)))
|
|
|
|
/// .get_matches_from_safe(vec![""]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
MissingSubcommand,
|
2015-10-01 01:45:35 +00:00
|
|
|
/// Occurs when no argument or subcommand has been supplied and
|
2015-09-09 02:38:44 +00:00
|
|
|
/// `AppSettings::ArgRequiredElseHelp` was used
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-09 02:38:44 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg, AppSettings, SubCommand};
|
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .setting(AppSettings::ArgRequiredElseHelp)
|
2015-11-01 14:02:37 +00:00
|
|
|
/// .subcommand(SubCommand::with_name("config")
|
2015-09-09 02:38:44 +00:00
|
|
|
/// .about("Used for configuration")
|
|
|
|
/// .arg(Arg::with_name("config_file")
|
|
|
|
/// .help("The configuration file to use")
|
|
|
|
/// .index(1)))
|
|
|
|
/// .get_matches_from_safe(vec![""]);
|
|
|
|
/// ```
|
|
|
|
MissingArgumentOrSubcommand,
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Error occurs when clap find argument while is was not expecting any
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .get_matches_from_safe(vec!["", "--arg"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
UnexpectedArgument,
|
|
|
|
/// Error occurs when argument was used multiple times and was not set as multiple.
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
2015-09-05 22:44:20 +00:00
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug")
|
|
|
|
/// .multiple(false))
|
|
|
|
/// .get_matches_from_safe(vec!["", "--debug", "--debug"]);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-07 01:07:46 +00:00
|
|
|
UnexpectedMultipleUsage,
|
2015-09-22 01:58:25 +00:00
|
|
|
/// Error occurs when argument contains invalid unicode characters
|
|
|
|
///
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-22 01:58:25 +00:00
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
|
|
|
/// # use std::os::unix::ffi::OsStringExt;
|
|
|
|
/// # use std::ffi::OsString;
|
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .arg(Arg::with_name("debug")
|
|
|
|
/// .short("u")
|
|
|
|
/// .takes_value(true))
|
2015-10-01 01:45:35 +00:00
|
|
|
/// .get_matches_from_safe(vec![OsString::from_vec(vec![0x20]),
|
2015-09-22 01:58:25 +00:00
|
|
|
/// OsString::from_vec(vec![0xE9])]);
|
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// ```
|
2015-10-28 09:43:01 +00:00
|
|
|
InvalidUnicode,
|
|
|
|
/// Not a true 'error' as it means `--help` or similar was used. The help message will be sent
|
|
|
|
/// to `stdout` unless the help is displayed due to an error (such as missing subcommands) at
|
|
|
|
/// which point it will be sent to `stderr`
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
|
|
|
/// # use clap::ClapErrorType;
|
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .get_matches_from_safe(vec!["", "--help"]);
|
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().error_type, ClapErrorType::HelpDisplayed);
|
|
|
|
/// ```
|
|
|
|
HelpDisplayed,
|
|
|
|
/// Not a true 'error' as it means `--version` or similar was used. The message will be sent
|
2015-10-28 13:57:47 +00:00
|
|
|
/// to `stdout`
|
2015-10-28 09:43:01 +00:00
|
|
|
///
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// # use clap::{App, Arg};
|
|
|
|
/// # use clap::ClapErrorType;
|
|
|
|
/// let result = App::new("myprog")
|
|
|
|
/// .get_matches_from_safe(vec!["", "--version"]);
|
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().error_type, ClapErrorType::VersionDisplayed);
|
|
|
|
/// ```
|
2015-10-28 14:23:59 +00:00
|
|
|
VersionDisplayed,
|
2015-10-29 04:23:05 +00:00
|
|
|
/// Represents an internal error, please consider filing a bug report if this happens!
|
|
|
|
InternalError,
|
2015-10-31 05:19:24 +00:00
|
|
|
/// Represents an I/O error, typically white writing to stderr or stdout
|
|
|
|
Io,
|
2015-11-08 15:29:45 +00:00
|
|
|
/// Represents an Rust Display Format error, typically white writing to stderr or stdout
|
|
|
|
Format,
|
2015-09-04 21:32:11 +00:00
|
|
|
}
|
|
|
|
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Command line argument parser error
|
|
|
|
#[derive(Debug)]
|
2015-09-04 21:32:11 +00:00
|
|
|
pub struct ClapError {
|
2015-09-05 21:17:32 +00:00
|
|
|
/// Formated error message
|
|
|
|
pub error: String,
|
2015-10-31 05:19:24 +00:00
|
|
|
/// The type of error
|
2015-09-07 01:07:46 +00:00
|
|
|
pub error_type: ClapErrorType,
|
2015-09-05 21:17:32 +00:00
|
|
|
}
|
|
|
|
|
2015-09-09 02:38:44 +00:00
|
|
|
impl ClapError {
|
2015-10-31 05:19:24 +00:00
|
|
|
/// Should the message be written to `stdout` or not
|
|
|
|
pub fn use_stderr(&self) -> bool {
|
|
|
|
match self.error_type {
|
|
|
|
ClapErrorType::HelpDisplayed | ClapErrorType::VersionDisplayed => false,
|
|
|
|
_ => true
|
|
|
|
}
|
|
|
|
}
|
2015-09-09 02:38:44 +00:00
|
|
|
/// Prints the error to `stderr` and exits with a status of `1`
|
|
|
|
pub fn exit(&self) -> ! {
|
2015-10-31 05:19:24 +00:00
|
|
|
if self.use_stderr() {
|
|
|
|
werr!("{}", self.error);
|
2015-11-03 03:56:05 +00:00
|
|
|
process::exit(1);
|
|
|
|
}
|
2015-10-30 03:49:39 +00:00
|
|
|
let out = io::stdout();
|
|
|
|
writeln!(&mut out.lock(), "{}", self.error).expect("Error writing ClapError to stdout");
|
2015-11-03 03:56:05 +00:00
|
|
|
process::exit(0);
|
|
|
|
}
|
2015-09-09 02:38:44 +00:00
|
|
|
}
|
|
|
|
|
2015-09-05 21:17:32 +00:00
|
|
|
impl Error for ClapError {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
&*self.error
|
|
|
|
}
|
2015-10-30 03:49:39 +00:00
|
|
|
|
|
|
|
fn cause(&self) -> Option<&Error> {
|
|
|
|
match self.error_type {
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
2015-09-05 21:17:32 +00:00
|
|
|
}
|
|
|
|
|
2015-10-30 03:49:39 +00:00
|
|
|
impl std_fmt::Display for ClapError {
|
|
|
|
fn fmt(&self, f: &mut std_fmt::Formatter) -> std_fmt::Result {
|
2015-09-05 21:17:32 +00:00
|
|
|
write!(f, "{}", self.error)
|
|
|
|
}
|
2015-09-07 01:07:46 +00:00
|
|
|
}
|
2015-10-31 05:19:24 +00:00
|
|
|
|
|
|
|
impl From<io::Error> for ClapError {
|
|
|
|
fn from(e: io::Error) -> Self {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} {}", Format::Error("error:"), e.description()),
|
|
|
|
error_type: ClapErrorType::Io,
|
|
|
|
}
|
|
|
|
}
|
2015-11-08 15:29:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<std_fmt::Error> for ClapError {
|
|
|
|
fn from(e: std_fmt::Error) -> Self {
|
|
|
|
ClapError {
|
|
|
|
error: format!("{} {}", Format::Error("error:"), e),
|
|
|
|
error_type: ClapErrorType::Format,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|