2016-09-05 19:29:40 +00:00
|
|
|
// Std
|
|
|
|
use std::convert::From;
|
2016-01-11 08:59:56 +00:00
|
|
|
use std::error::Error as StdError;
|
2015-10-30 03:49:39 +00:00
|
|
|
use std::fmt as std_fmt;
|
2016-01-11 08:59:56 +00:00
|
|
|
use std::fmt::Display;
|
2015-10-30 03:49:39 +00:00
|
|
|
use std::io::{self, Write};
|
2016-09-05 19:29:40 +00:00
|
|
|
use std::process;
|
2016-01-11 08:59:56 +00:00
|
|
|
use std::result::Result as StdResult;
|
2016-09-05 21:03:45 +00:00
|
|
|
|
|
|
|
// Internal
|
2018-08-02 01:04:11 +00:00
|
|
|
use build::{Arg, ArgGroup};
|
2018-06-12 15:42:03 +00:00
|
|
|
use output::fmt::{ColorWhen, Colorizer, ColorizerOption};
|
|
|
|
use parse::features::suggestions;
|
2015-10-30 03:49:39 +00:00
|
|
|
|
2016-05-14 20:25:00 +00:00
|
|
|
/// Short hand for [`Result`] type
|
2018-03-19 20:53:19 +00:00
|
|
|
///
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
|
2016-01-11 08:59:56 +00:00
|
|
|
pub type Result<T> = StdResult<T, Error>;
|
2015-09-05 21:17:32 +00:00
|
|
|
|
2016-01-26 19:02:10 +00:00
|
|
|
/// Command line argument parser kind of error
|
2015-10-31 05:19:24 +00:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2016-01-11 08:59:56 +00:00
|
|
|
pub enum ErrorKind {
|
2016-10-09 12:38:31 +00:00
|
|
|
/// Occurs when an [`Arg`] has a set of possible values,
|
|
|
|
/// and the user provides a value which isn't in that set.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .arg(Arg::with_name("speed")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .possible_value("fast")
|
|
|
|
/// .possible_value("slow"))
|
2017-02-18 02:55:31 +00:00
|
|
|
/// .get_matches_from_safe(vec!["prog", "other"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
2016-01-22 04:18:52 +00:00
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::InvalidValue);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Arg`]: ./struct.Arg.html
|
2015-09-05 21:17:32 +00:00
|
|
|
InvalidValue,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-10-09 04:44:45 +00:00
|
|
|
/// Occurs when a user provides a flag, option, argument or subcommand which isn't defined.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2018-04-21 18:59:19 +00:00
|
|
|
/// .arg(Arg::from("--flag 'some flag'"))
|
2017-02-18 02:55:31 +00:00
|
|
|
/// .get_matches_from_safe(vec!["prog", "--other"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::UnknownArgument);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
UnknownArgument,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-10-09 04:44:45 +00:00
|
|
|
/// Occurs when the user provides an unrecognized [`SubCommand`] which meets the threshold for
|
2016-11-20 19:41:15 +00:00
|
|
|
/// being similar enough to an existing subcommand.
|
2016-10-09 04:44:45 +00:00
|
|
|
/// If it doesn't meet the threshold, or the 'suggestions' feature is disabled,
|
|
|
|
/// the more general [`UnknownArgument`] error is returned.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2017-11-28 12:30:06 +00:00
|
|
|
#[cfg_attr(not(feature = "suggestions"), doc = " ```no_run")]
|
|
|
|
#[cfg_attr(feature = "suggestions", doc = " ```")]
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind, SubCommand};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
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)))
|
2017-02-18 02:55:31 +00:00
|
|
|
/// .get_matches_from_safe(vec!["prog", "confi"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::InvalidSubcommand);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`SubCommand`]: ./struct.SubCommand.html
|
|
|
|
/// [`UnknownArgument`]: ./enum.ErrorKind.html#variant.UnknownArgument
|
2015-09-05 21:17:32 +00:00
|
|
|
InvalidSubcommand,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-10-09 04:44:45 +00:00
|
|
|
/// Occurs when the user provides an unrecognized [`SubCommand`] which either
|
|
|
|
/// doesn't meet the threshold for being similar enough to an existing subcommand,
|
2018-03-19 20:53:19 +00:00
|
|
|
/// or the 'suggestions' feature is disabled.
|
2016-10-09 04:44:45 +00:00
|
|
|
/// Otherwise the more detailed [`InvalidSubcommand`] error is returned.
|
2016-03-15 02:09:17 +00:00
|
|
|
///
|
|
|
|
/// This error typically happens when passing additional subcommand names to the `help`
|
2016-05-14 20:25:00 +00:00
|
|
|
/// subcommand. Otherwise, the more general [`UnknownArgument`] error is used.
|
2016-03-15 02:09:17 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{App, Arg, ErrorKind, SubCommand};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2016-03-15 02:09:17 +00:00
|
|
|
/// .subcommand(SubCommand::with_name("config")
|
|
|
|
/// .about("Used for configuration")
|
|
|
|
/// .arg(Arg::with_name("config_file")
|
|
|
|
/// .help("The configuration file to use")
|
|
|
|
/// .index(1)))
|
2017-02-18 02:55:31 +00:00
|
|
|
/// .get_matches_from_safe(vec!["prog", "help", "nothing"]);
|
2016-03-15 02:09:17 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::UnrecognizedSubcommand);
|
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`SubCommand`]: ./struct.SubCommand.html
|
|
|
|
/// [`InvalidSubcommand`]: ./enum.ErrorKind.html#variant.InvalidSubcommand
|
|
|
|
/// [`UnknownArgument`]: ./enum.ErrorKind.html#variant.UnknownArgument
|
2016-03-15 02:09:17 +00:00
|
|
|
UnrecognizedSubcommand,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-29 02:51:50 +00:00
|
|
|
/// Occurs when the user provides an empty value for an option that does not allow empty
|
|
|
|
/// values.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2018-01-31 02:57:29 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind, ArgSettings};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let res = App::new("prog")
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .arg(Arg::with_name("color")
|
2018-01-31 02:57:29 +00:00
|
|
|
/// .setting(ArgSettings::TakesValue)
|
|
|
|
/// .long("color"))
|
|
|
|
/// .try_get_matches_from(vec!["prog", "--color="]);
|
2016-01-26 19:02:10 +00:00
|
|
|
/// assert!(res.is_err());
|
|
|
|
/// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
EmptyValue,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
/// Occurs when the user provides a value for an argument with a custom validation and the
|
|
|
|
/// value fails that validation.
|
2015-10-05 00:09:12 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2016-01-11 08:59:56 +00:00
|
|
|
/// fn is_numeric(val: String) -> Result<(), String> {
|
|
|
|
/// match val.parse::<i64>() {
|
|
|
|
/// Ok(..) => Ok(()),
|
|
|
|
/// Err(..) => Err(String::from("Value wasn't a number!")),
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .arg(Arg::with_name("num")
|
|
|
|
/// .validator(is_numeric))
|
2018-01-31 02:57:29 +00:00
|
|
|
/// .try_get_matches_from(vec!["prog", "NotANumber"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::ValueValidation);
|
2015-10-05 00:09:12 +00:00
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
ValueValidation,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
/// Occurs when a user provides more values for an argument than were defined by setting
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Arg::max_values`].
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2016-01-26 19:02:10 +00:00
|
|
|
/// .arg(Arg::with_name("arg")
|
|
|
|
/// .multiple(true)
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .max_values(2))
|
2018-01-31 02:57:29 +00:00
|
|
|
/// .try_get_matches_from(vec!["prog", "too", "many", "values"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::TooManyValues);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Arg::max_values`]: ./struct.Arg.html#method.max_values
|
2015-10-05 00:09:12 +00:00
|
|
|
TooManyValues,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
/// Occurs when the user provides fewer values for an argument than were defined by setting
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Arg::min_values`].
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .arg(Arg::with_name("some_opt")
|
|
|
|
/// .long("opt")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .min_values(3))
|
2018-01-31 02:57:29 +00:00
|
|
|
/// .try_get_matches_from(vec!["prog", "--opt", "too", "few"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::TooFewValues);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Arg::min_values`]: ./struct.Arg.html#method.min_values
|
2015-09-05 21:17:32 +00:00
|
|
|
TooFewValues,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
/// Occurs when the user provides a different number of values for an argument than what's
|
2016-05-14 20:25:00 +00:00
|
|
|
/// been defined by setting [`Arg::number_of_values`] or than was implicitly set by
|
|
|
|
/// [`Arg::value_names`].
|
2015-10-05 00:09:12 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .arg(Arg::with_name("some_opt")
|
|
|
|
/// .long("opt")
|
|
|
|
/// .takes_value(true)
|
|
|
|
/// .number_of_values(2))
|
2018-01-31 02:57:29 +00:00
|
|
|
/// .try_get_matches_from(vec!["prog", "--opt", "wrong"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::WrongNumberOfValues);
|
2015-10-05 00:09:12 +00:00
|
|
|
/// ```
|
2018-06-30 23:33:34 +00:00
|
|
|
///
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Arg::number_of_values`]: ./struct.Arg.html#method.number_of_values
|
|
|
|
/// [`Arg::value_names`]: ./struct.Arg.html#method.value_names
|
2016-01-11 08:59:56 +00:00
|
|
|
WrongNumberOfValues,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-26 19:02:10 +00:00
|
|
|
/// Occurs when the user provides two values which conflict with each other and can't be used
|
|
|
|
/// together.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .arg(Arg::with_name("debug")
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .long("debug")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .conflicts_with("color"))
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .arg(Arg::with_name("color")
|
|
|
|
/// .long("color"))
|
2018-01-31 02:57:29 +00:00
|
|
|
/// .try_get_matches_from(vec!["prog", "--debug", "--color"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::ArgumentConflict);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
ArgumentConflict,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-29 02:51:50 +00:00
|
|
|
/// Occurs when the user does not provide one or more required arguments.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .arg(Arg::with_name("debug")
|
|
|
|
/// .required(true))
|
2017-02-18 02:55:31 +00:00
|
|
|
/// .get_matches_from_safe(vec!["prog"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-05 21:17:32 +00:00
|
|
|
MissingRequiredArgument,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-05-14 20:25:00 +00:00
|
|
|
/// Occurs when a subcommand is required (as defined by [`AppSettings::SubcommandRequired`]),
|
|
|
|
/// but the user does not provide one.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{App, AppSettings, SubCommand, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let err = App::new("prog")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .setting(AppSettings::SubcommandRequired)
|
2016-01-26 19:02:10 +00:00
|
|
|
/// .subcommand(SubCommand::with_name("test"))
|
|
|
|
/// .get_matches_from_safe(vec![
|
|
|
|
/// "myprog",
|
|
|
|
/// ]);
|
|
|
|
/// assert!(err.is_err());
|
|
|
|
/// assert_eq!(err.unwrap_err().kind, ErrorKind::MissingSubcommand);
|
|
|
|
/// # ;
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`AppSettings::SubcommandRequired`]: ./enum.AppSettings.html#variant.SubcommandRequired
|
2015-09-05 21:17:32 +00:00
|
|
|
MissingSubcommand,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-05-14 20:25:00 +00:00
|
|
|
/// Occurs when either an argument or [`SubCommand`] is required, as defined by
|
2016-10-09 12:38:31 +00:00
|
|
|
/// [`AppSettings::ArgRequiredElseHelp`], but the user did not provide one.
|
2015-09-09 02:38:44 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-09 02:38:44 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, AppSettings, ErrorKind, SubCommand};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2015-09-09 02:38:44 +00:00
|
|
|
/// .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")
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .help("The configuration file to use")))
|
2017-02-18 02:55:31 +00:00
|
|
|
/// .get_matches_from_safe(vec!["prog"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::MissingArgumentOrSubcommand);
|
2015-09-09 02:38:44 +00:00
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`SubCommand`]: ./struct.SubCommand.html
|
|
|
|
/// [`AppSettings::ArgRequiredElseHelp`]: ./enum.AppSettings.html#variant.ArgRequiredElseHelp
|
2015-09-09 02:38:44 +00:00
|
|
|
MissingArgumentOrSubcommand,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
|
|
|
/// Occurs when the user provides multiple values to an argument which doesn't allow that.
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-05 21:17:32 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .arg(Arg::with_name("debug")
|
2016-01-26 19:02:10 +00:00
|
|
|
/// .long("debug")
|
2015-09-05 22:44:20 +00:00
|
|
|
/// .multiple(false))
|
2017-02-18 02:55:31 +00:00
|
|
|
/// .get_matches_from_safe(vec!["prog", "--debug", "--debug"]);
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::UnexpectedMultipleUsage);
|
2015-09-05 22:12:46 +00:00
|
|
|
/// ```
|
2015-09-07 01:07:46 +00:00
|
|
|
UnexpectedMultipleUsage,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
/// Occurs when the user provides a value containing invalid UTF-8 for an argument and
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`AppSettings::StrictUtf8`] is set.
|
2016-01-11 08:59:56 +00:00
|
|
|
///
|
2018-03-19 20:53:19 +00:00
|
|
|
/// # Platform Specific
|
2015-09-22 01:58:25 +00:00
|
|
|
///
|
2016-01-11 08:59:56 +00:00
|
|
|
/// Non-Windows platforms only (such as Linux, Unix, OSX, etc.)
|
2015-09-22 01:58:25 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-22 01:58:25 +00:00
|
|
|
///
|
2017-11-28 12:30:06 +00:00
|
|
|
#[cfg_attr(not(unix), doc = " ```ignore")]
|
|
|
|
#[cfg_attr(unix, doc = " ```")]
|
2016-01-22 17:58:56 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind, AppSettings};
|
2015-09-22 01:58:25 +00:00
|
|
|
/// # use std::os::unix::ffi::OsStringExt;
|
|
|
|
/// # use std::ffi::OsString;
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
2016-01-22 17:58:56 +00:00
|
|
|
/// .setting(AppSettings::StrictUtf8)
|
|
|
|
/// .arg(Arg::with_name("utf8")
|
2018-07-23 19:09:42 +00:00
|
|
|
/// .short('u')
|
2015-09-22 01:58:25 +00:00
|
|
|
/// .takes_value(true))
|
2016-01-11 08:59:56 +00:00
|
|
|
/// .get_matches_from_safe(vec![OsString::from("myprog"),
|
2016-10-05 09:07:28 +00:00
|
|
|
/// OsString::from("-u"),
|
2016-01-22 17:58:56 +00:00
|
|
|
/// OsString::from_vec(vec![0xE9])]);
|
2015-09-22 01:58:25 +00:00
|
|
|
/// assert!(result.is_err());
|
2016-01-11 08:59:56 +00:00
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::InvalidUtf8);
|
2015-09-22 01:58:25 +00:00
|
|
|
/// ```
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`AppSettings::StrictUtf8`]: ./enum.AppSettings.html#variant.StrictUtf8
|
2016-01-11 08:59:56 +00:00
|
|
|
InvalidUtf8,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
|
|
|
/// Not a true "error" as it means `--help` or similar was used.
|
|
|
|
/// The help message will be sent to `stdout`.
|
2015-10-28 09:43:01 +00:00
|
|
|
///
|
2016-01-11 08:59:56 +00:00
|
|
|
/// **Note**: If the help is displayed due to an error (such as missing subcommands) it will
|
2016-01-29 02:51:50 +00:00
|
|
|
/// be sent to `stderr` instead of `stdout`.
|
2015-10-28 09:43:01 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
|
|
|
/// .get_matches_from_safe(vec!["prog", "--help"]);
|
2015-10-28 09:43:01 +00:00
|
|
|
/// assert!(result.is_err());
|
2016-01-22 04:18:52 +00:00
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::HelpDisplayed);
|
2015-10-28 09:43:01 +00:00
|
|
|
/// ```
|
|
|
|
HelpDisplayed,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
|
|
|
/// Not a true "error" as it means `--version` or similar was used.
|
|
|
|
/// The message will be sent to `stdout`.
|
2015-10-28 09:43:01 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2016-01-22 04:18:52 +00:00
|
|
|
/// # use clap::{App, Arg, ErrorKind};
|
2017-02-18 02:55:31 +00:00
|
|
|
/// let result = App::new("prog")
|
|
|
|
/// .get_matches_from_safe(vec!["prog", "--version"]);
|
2015-10-28 09:43:01 +00:00
|
|
|
/// assert!(result.is_err());
|
2016-01-22 04:18:52 +00:00
|
|
|
/// assert_eq!(result.unwrap_err().kind, ErrorKind::VersionDisplayed);
|
2015-10-28 09:43:01 +00:00
|
|
|
/// ```
|
2015-10-28 14:23:59 +00:00
|
|
|
VersionDisplayed,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
2016-05-14 20:25:00 +00:00
|
|
|
/// Occurs when using the [`value_t!`] and [`values_t!`] macros to convert an argument value
|
|
|
|
/// into type `T`, but the argument you requested wasn't used. I.e. you asked for an argument
|
|
|
|
/// with name `config` to be converted, but `config` wasn't used by the user.
|
|
|
|
/// [`value_t!`]: ./macro.value_t!.html
|
|
|
|
/// [`values_t!`]: ./macro.values_t!.html
|
2016-01-22 04:18:52 +00:00
|
|
|
ArgumentNotFound,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
|
|
|
/// Represents an [I/O error].
|
|
|
|
/// Can occur when writing to `stderr` or `stdout` or reading a configuration file.
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [I/O error]: https://doc.rust-lang.org/std/io/struct.Error.html
|
2015-10-31 05:19:24 +00:00
|
|
|
Io,
|
2016-10-09 12:38:31 +00:00
|
|
|
|
|
|
|
/// Represents a [Format error] (which is a part of [`Display`]).
|
|
|
|
/// Typically caused by writing to `stderr` or `stdout`.
|
2018-06-30 23:33:34 +00:00
|
|
|
///
|
2016-05-14 20:25:00 +00:00
|
|
|
/// [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
|
|
|
|
/// [Format error]: https://doc.rust-lang.org/std/fmt/struct.Error.html
|
2015-11-08 15:29:45 +00:00
|
|
|
Format,
|
2015-09-04 21:32:11 +00:00
|
|
|
}
|
|
|
|
|
2016-01-29 02:51:50 +00:00
|
|
|
/// Command Line Argument Parser Error
|
2015-09-05 21:17:32 +00:00
|
|
|
#[derive(Debug)]
|
2016-01-11 08:59:56 +00:00
|
|
|
pub struct Error {
|
2018-03-19 20:53:19 +00:00
|
|
|
/// Formatted error message
|
2016-01-11 08:59:56 +00:00
|
|
|
pub message: String,
|
2015-10-31 05:19:24 +00:00
|
|
|
/// The type of error
|
2016-01-11 08:59:56 +00:00
|
|
|
pub kind: ErrorKind,
|
|
|
|
/// Any additional information passed along, such as the argument name that caused the error
|
|
|
|
pub info: Option<Vec<String>>,
|
2015-09-05 21:17:32 +00:00
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl Error {
|
2015-10-31 05:19:24 +00:00
|
|
|
/// Should the message be written to `stdout` or not
|
|
|
|
pub fn use_stderr(&self) -> bool {
|
2016-01-11 08:59:56 +00:00
|
|
|
match self.kind {
|
2017-11-28 12:30:06 +00:00
|
|
|
ErrorKind::HelpDisplayed | ErrorKind::VersionDisplayed => false,
|
2015-11-09 07:22:12 +00:00
|
|
|
_ => true,
|
2015-10-31 05:19:24 +00:00
|
|
|
}
|
|
|
|
}
|
2016-01-11 08:59:56 +00:00
|
|
|
|
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() {
|
2016-01-11 08:59:56 +00:00
|
|
|
wlnerr!("{}", self.message);
|
2015-11-03 03:56:05 +00:00
|
|
|
process::exit(1);
|
|
|
|
}
|
2015-10-30 03:49:39 +00:00
|
|
|
let out = io::stdout();
|
2016-01-11 08:59:56 +00:00
|
|
|
writeln!(&mut out.lock(), "{}", self.message).expect("Error writing Error to stdout");
|
2015-11-03 03:56:05 +00:00
|
|
|
process::exit(0);
|
|
|
|
}
|
2016-01-11 08:59:56 +00:00
|
|
|
|
2016-05-09 01:33:27 +00:00
|
|
|
#[doc(hidden)]
|
2016-11-20 19:41:15 +00:00
|
|
|
pub fn write_to<W: Write>(&self, w: &mut W) -> io::Result<()> { write!(w, "{}", self.message) }
|
2016-05-09 01:33:27 +00:00
|
|
|
|
2018-08-02 01:04:11 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
pub fn group_conflict<'a, 'b, O, U>(
|
|
|
|
group: &ArgGroup,
|
|
|
|
other: Option<O>,
|
|
|
|
usage: U,
|
|
|
|
color: ColorWhen,
|
|
|
|
) -> Self
|
|
|
|
where
|
|
|
|
O: Into<String>,
|
|
|
|
U: Display,
|
|
|
|
{
|
|
|
|
let mut v = vec![group.name.to_owned()];
|
|
|
|
let c = Colorizer::new(ColorizerOption {
|
|
|
|
use_stderr: true,
|
|
|
|
when: color,
|
|
|
|
});
|
|
|
|
Error {
|
|
|
|
message: format!(
|
|
|
|
"{} The argument '{}' cannot be used with {}\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(group.name),
|
|
|
|
match other {
|
|
|
|
Some(name) => {
|
|
|
|
let n = name.into();
|
|
|
|
v.push(n.clone());
|
|
|
|
c.warning(format!("'{}'", n))
|
|
|
|
}
|
|
|
|
None => c.none("one or more of the other specified arguments".to_owned()),
|
|
|
|
},
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
|
|
|
kind: ErrorKind::ArgumentConflict,
|
|
|
|
info: Some(v),
|
|
|
|
}
|
|
|
|
}
|
2016-01-11 08:59:56 +00:00
|
|
|
#[doc(hidden)]
|
2018-01-09 15:40:29 +00:00
|
|
|
pub fn argument_conflict<'a, 'b, O, U>(
|
2018-01-22 23:19:53 +00:00
|
|
|
arg: &Arg,
|
2017-11-28 12:30:06 +00:00
|
|
|
other: Option<O>,
|
|
|
|
usage: U,
|
|
|
|
color: ColorWhen,
|
|
|
|
) -> Self
|
|
|
|
where
|
|
|
|
O: Into<String>,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2018-01-22 23:19:53 +00:00
|
|
|
let mut v = vec![arg.name.to_owned()];
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The argument '{}' cannot be used with {}\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(&*arg.to_string()),
|
|
|
|
match other {
|
|
|
|
Some(name) => {
|
|
|
|
let n = name.into();
|
|
|
|
v.push(n.clone());
|
|
|
|
c.warning(format!("'{}'", n))
|
|
|
|
}
|
|
|
|
None => c.none("one or more of the other specified arguments".to_owned()),
|
|
|
|
},
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::ArgumentConflict,
|
2016-09-05 19:29:40 +00:00
|
|
|
info: Some(v),
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2018-01-22 23:19:53 +00:00
|
|
|
pub fn empty_value<'a, 'b, U>(arg: &Arg, usage: U, color: ColorWhen) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The argument '{}' requires a value but none was supplied\
|
|
|
|
\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(arg.to_string()),
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::EmptyValue,
|
2018-01-22 23:19:53 +00:00
|
|
|
info: Some(vec![arg.name.to_owned()]),
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2018-01-09 15:40:29 +00:00
|
|
|
pub fn invalid_value<'a, 'b, B, G, U>(
|
2017-11-28 12:30:06 +00:00
|
|
|
bad_val: B,
|
|
|
|
good_vals: &[G],
|
2018-01-22 23:19:53 +00:00
|
|
|
arg: &Arg,
|
2017-11-28 12:30:06 +00:00
|
|
|
usage: U,
|
|
|
|
color: ColorWhen,
|
|
|
|
) -> Self
|
|
|
|
where
|
|
|
|
B: AsRef<str>,
|
|
|
|
G: AsRef<str> + Display,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-07-05 20:25:35 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2017-11-28 12:30:06 +00:00
|
|
|
let suffix = suggestions::did_you_mean_value_suffix(bad_val.as_ref(), good_vals.iter());
|
2016-01-11 08:59:56 +00:00
|
|
|
|
|
|
|
let mut sorted = vec![];
|
|
|
|
for v in good_vals {
|
2016-07-05 20:25:35 +00:00
|
|
|
let val = format!("{}", c.good(v));
|
|
|
|
sorted.push(val);
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
sorted.sort();
|
2016-07-05 20:04:00 +00:00
|
|
|
let valid_values = sorted.join(", ");
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} '{}' isn't a valid value for '{}'\n\t\
|
2018-02-06 03:24:44 +00:00
|
|
|
[possible values: {}]\n\
|
2017-11-28 12:30:06 +00:00
|
|
|
{}\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(bad_val.as_ref()),
|
|
|
|
c.warning(arg.to_string()),
|
|
|
|
valid_values,
|
|
|
|
suffix.0,
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::InvalidValue,
|
2018-01-22 23:19:53 +00:00
|
|
|
info: Some(vec![arg.name.to_owned(), bad_val.as_ref().to_owned()]),
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2017-11-28 12:30:06 +00:00
|
|
|
pub fn invalid_subcommand<S, D, N, U>(
|
|
|
|
subcmd: S,
|
|
|
|
did_you_mean: D,
|
|
|
|
name: N,
|
|
|
|
usage: U,
|
|
|
|
color: ColorWhen,
|
|
|
|
) -> Self
|
|
|
|
where
|
|
|
|
S: Into<String>,
|
|
|
|
D: AsRef<str> + Display,
|
|
|
|
N: Display,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
|
|
|
let s = subcmd.into();
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The subcommand '{}' wasn't recognized\n\t\
|
|
|
|
Did you mean '{}'?\n\n\
|
|
|
|
If you believe you received this message in error, try \
|
|
|
|
re-running with '{} {} {}'\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(&*s),
|
|
|
|
c.good(did_you_mean.as_ref()),
|
|
|
|
name,
|
|
|
|
c.good("--"),
|
|
|
|
&*s,
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::InvalidSubcommand,
|
|
|
|
info: Some(vec![s]),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-15 02:09:17 +00:00
|
|
|
#[doc(hidden)]
|
2017-05-26 22:48:16 +00:00
|
|
|
pub fn unrecognized_subcommand<S, N>(subcmd: S, name: N, color: ColorWhen) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
S: Into<String>,
|
|
|
|
N: Display,
|
2016-03-15 02:09:17 +00:00
|
|
|
{
|
|
|
|
let s = subcmd.into();
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-03-15 02:09:17 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The subcommand '{}' wasn't recognized\n\n\
|
|
|
|
{}\n\t\
|
|
|
|
{} help <subcommands>...\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(&*s),
|
|
|
|
c.warning("USAGE:"),
|
|
|
|
name,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-03-15 02:09:17 +00:00
|
|
|
kind: ErrorKind::UnrecognizedSubcommand,
|
|
|
|
info: Some(vec![s]),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
#[doc(hidden)]
|
2017-05-26 22:48:16 +00:00
|
|
|
pub fn missing_required_argument<R, U>(required: R, usage: U, color: ColorWhen) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
R: Display,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The following required arguments were not provided:{}\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
required,
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::MissingRequiredArgument,
|
|
|
|
info: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2017-05-26 22:48:16 +00:00
|
|
|
pub fn missing_subcommand<N, U>(name: N, usage: U, color: ColorWhen) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
N: AsRef<str> + Display,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} '{}' requires a subcommand, but one was not provided\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(name),
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::MissingSubcommand,
|
|
|
|
info: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2017-05-26 22:48:16 +00:00
|
|
|
pub fn invalid_utf8<U>(usage: U, color: ColorWhen) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} Invalid UTF-8 was detected in one or more arguments\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::InvalidUtf8,
|
|
|
|
info: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2018-01-22 23:19:53 +00:00
|
|
|
pub fn too_many_values<'a, 'b, V, U>(val: V, arg: &Arg, usage: U, color: ColorWhen) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
V: AsRef<str> + Display + ToOwned,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
|
|
|
let v = val.as_ref();
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The value '{}' was provided to '{}', but it wasn't expecting \
|
|
|
|
any more values\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(v),
|
|
|
|
c.warning(arg.to_string()),
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::TooManyValues,
|
2018-01-22 23:19:53 +00:00
|
|
|
info: Some(vec![arg.name.to_owned(), v.to_owned()]),
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2018-01-09 15:40:29 +00:00
|
|
|
pub fn too_few_values<'a, 'b, U>(
|
2018-01-22 23:19:53 +00:00
|
|
|
arg: &Arg,
|
2017-11-28 12:30:06 +00:00
|
|
|
min_vals: u64,
|
|
|
|
curr_vals: usize,
|
|
|
|
usage: U,
|
|
|
|
color: ColorWhen,
|
|
|
|
) -> Self
|
|
|
|
where
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The argument '{}' requires at least {} values, but only {} w{} \
|
|
|
|
provided\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(arg.to_string()),
|
|
|
|
c.warning(min_vals.to_string()),
|
|
|
|
c.warning(curr_vals.to_string()),
|
|
|
|
if curr_vals > 1 { "ere" } else { "as" },
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::TooFewValues,
|
2018-01-22 23:19:53 +00:00
|
|
|
info: Some(vec![arg.name.to_owned()]),
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2018-01-25 04:05:05 +00:00
|
|
|
pub fn value_validation<'a, 'b>(arg: Option<&Arg>, err: String, color: ColorWhen) -> Self {
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} Invalid value{}: {}",
|
|
|
|
c.error("error:"),
|
|
|
|
if let Some(a) = arg {
|
|
|
|
format!(" for '{}'", c.warning(a.to_string()))
|
|
|
|
} else {
|
|
|
|
"".to_string()
|
|
|
|
},
|
|
|
|
err
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::ValueValidation,
|
|
|
|
info: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-30 08:07:44 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
pub fn value_validation_auto(err: String) -> Self {
|
2018-01-22 23:19:53 +00:00
|
|
|
let n: Option<&Arg> = None;
|
2017-05-26 22:48:16 +00:00
|
|
|
Error::value_validation(n, err, ColorWhen::Auto)
|
2016-05-30 08:07:44 +00:00
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
#[doc(hidden)]
|
2018-01-09 15:40:29 +00:00
|
|
|
pub fn wrong_number_of_values<'a, 'b, S, U>(
|
2018-01-22 23:19:53 +00:00
|
|
|
arg: &Arg,
|
2017-11-28 12:30:06 +00:00
|
|
|
num_vals: u64,
|
|
|
|
curr_vals: usize,
|
|
|
|
suffix: S,
|
|
|
|
usage: U,
|
|
|
|
color: ColorWhen,
|
|
|
|
) -> Self
|
|
|
|
where
|
|
|
|
S: Display,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The argument '{}' requires {} values, but {} w{} \
|
|
|
|
provided\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(arg.to_string()),
|
|
|
|
c.warning(num_vals.to_string()),
|
|
|
|
c.warning(curr_vals.to_string()),
|
|
|
|
suffix,
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::WrongNumberOfValues,
|
2018-01-22 23:19:53 +00:00
|
|
|
info: Some(vec![arg.name.to_owned()]),
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2018-01-22 23:19:53 +00:00
|
|
|
pub fn unexpected_multiple_usage<'a, 'b, U>(arg: &Arg, usage: U, color: ColorWhen) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The argument '{}' was provided more than once, but cannot \
|
|
|
|
be used multiple times\n\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(arg.to_string()),
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::UnexpectedMultipleUsage,
|
2018-01-22 23:19:53 +00:00
|
|
|
info: Some(vec![arg.name.to_owned()]),
|
2016-01-11 08:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2017-11-28 12:30:06 +00:00
|
|
|
pub fn unknown_argument<A, U>(arg: A, did_you_mean: &str, usage: U, color: ColorWhen) -> Self
|
|
|
|
where
|
|
|
|
A: Into<String>,
|
|
|
|
U: Display,
|
2016-01-11 08:59:56 +00:00
|
|
|
{
|
|
|
|
let a = arg.into();
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-01-11 08:59:56 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} Found argument '{}' which wasn't expected, or isn't valid in \
|
|
|
|
this context{}\n\
|
|
|
|
{}\n\n\
|
|
|
|
For more information try {}",
|
|
|
|
c.error("error:"),
|
|
|
|
c.warning(&*a),
|
|
|
|
if did_you_mean.is_empty() {
|
|
|
|
"\n".to_owned()
|
|
|
|
} else {
|
|
|
|
format!("{}\n", did_you_mean)
|
|
|
|
},
|
|
|
|
usage,
|
|
|
|
c.good("--help")
|
|
|
|
),
|
2016-01-11 08:59:56 +00:00
|
|
|
kind: ErrorKind::UnknownArgument,
|
|
|
|
info: Some(vec![a]),
|
|
|
|
}
|
|
|
|
}
|
2016-01-22 04:18:52 +00:00
|
|
|
|
|
|
|
#[doc(hidden)]
|
2017-05-26 22:48:16 +00:00
|
|
|
pub fn io_error(e: &Error, color: ColorWhen) -> Self {
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2016-09-05 19:29:40 +00:00
|
|
|
when: color,
|
2017-05-26 22:48:16 +00:00
|
|
|
});
|
2016-05-30 08:07:44 +00:00
|
|
|
Error {
|
|
|
|
message: format!("{} {}", c.error("error:"), e.description()),
|
|
|
|
kind: ErrorKind::Io,
|
|
|
|
info: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
pub fn argument_not_found_auto<A>(arg: A) -> Self
|
2017-11-28 12:30:06 +00:00
|
|
|
where
|
|
|
|
A: Into<String>,
|
2016-01-22 04:18:52 +00:00
|
|
|
{
|
|
|
|
let a = arg.into();
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-05-30 08:07:44 +00:00
|
|
|
use_stderr: true,
|
2017-05-26 22:48:16 +00:00
|
|
|
when: ColorWhen::Auto,
|
|
|
|
});
|
2016-01-22 04:18:52 +00:00
|
|
|
Error {
|
2017-11-28 12:30:06 +00:00
|
|
|
message: format!(
|
|
|
|
"{} The argument '{}' wasn't found",
|
|
|
|
c.error("error:"),
|
|
|
|
a.clone()
|
|
|
|
),
|
2016-01-22 04:18:52 +00:00
|
|
|
kind: ErrorKind::ArgumentNotFound,
|
|
|
|
info: Some(vec![a]),
|
|
|
|
}
|
|
|
|
}
|
2016-08-29 21:39:52 +00:00
|
|
|
|
|
|
|
/// Create an error with a custom description.
|
|
|
|
///
|
|
|
|
/// This can be used in combination with `Error::exit` to exit your program
|
|
|
|
/// with a custom error message.
|
|
|
|
pub fn with_description(description: &str, kind: ErrorKind) -> Self {
|
2017-05-27 16:10:42 +00:00
|
|
|
let c = Colorizer::new(ColorizerOption {
|
2016-08-29 21:39:52 +00:00
|
|
|
use_stderr: true,
|
2017-05-26 22:48:16 +00:00
|
|
|
when: ColorWhen::Auto,
|
|
|
|
});
|
2016-08-29 21:39:52 +00:00
|
|
|
Error {
|
|
|
|
message: format!("{} {}", c.error("error:"), description),
|
|
|
|
kind: kind,
|
|
|
|
info: None,
|
|
|
|
}
|
|
|
|
}
|
2015-09-09 02:38:44 +00:00
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl StdError for Error {
|
2016-11-20 19:41:15 +00:00
|
|
|
fn description(&self) -> &str { &*self.message }
|
2015-09-05 21:17:32 +00:00
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl Display for Error {
|
2016-11-20 19:41:15 +00:00
|
|
|
fn fmt(&self, f: &mut std_fmt::Formatter) -> std_fmt::Result { writeln!(f, "{}", self.message) }
|
2015-09-07 01:07:46 +00:00
|
|
|
}
|
2015-10-31 05:19:24 +00:00
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl From<io::Error> for Error {
|
2016-11-20 19:41:15 +00:00
|
|
|
fn from(e: io::Error) -> Self { Error::with_description(e.description(), ErrorKind::Io) }
|
2015-11-08 15:29:45 +00:00
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl From<std_fmt::Error> for Error {
|
2015-11-08 15:29:45 +00:00
|
|
|
fn from(e: std_fmt::Error) -> Self {
|
2016-08-29 21:39:52 +00:00
|
|
|
Error::with_description(e.description(), ErrorKind::Format)
|
2015-11-08 15:29:45 +00:00
|
|
|
}
|
|
|
|
}
|