summaryrefslogtreecommitdiffstats
path: root/vendor/clap/src/error
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vendor/clap-3.2.20/src/error/context.rs (renamed from vendor/clap/src/error/context.rs)0
-rw-r--r--vendor/clap/src/error/kind.rs440
-rw-r--r--vendor/clap/src/error/mod.rs1158
3 files changed, 0 insertions, 1598 deletions
diff --git a/vendor/clap/src/error/context.rs b/vendor/clap-3.2.20/src/error/context.rs
index 985cd4d70..985cd4d70 100644
--- a/vendor/clap/src/error/context.rs
+++ b/vendor/clap-3.2.20/src/error/context.rs
diff --git a/vendor/clap/src/error/kind.rs b/vendor/clap/src/error/kind.rs
deleted file mode 100644
index 21256609a..000000000
--- a/vendor/clap/src/error/kind.rs
+++ /dev/null
@@ -1,440 +0,0 @@
-/// Command line argument parser kind of error
-#[derive(Debug, Copy, Clone, PartialEq)]
-#[non_exhaustive]
-pub enum ErrorKind {
- /// Occurs when an [`Arg`][crate::Arg] has a set of possible values,
- /// and the user provides a value which isn't in that set.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("speed")
- /// .value_parser(["fast", "slow"]))
- /// .try_get_matches_from(vec!["prog", "other"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue);
- /// ```
- InvalidValue,
-
- /// Occurs when a user provides a flag, option, argument or subcommand which isn't defined.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(arg!(--flag "some flag"))
- /// .try_get_matches_from(vec!["prog", "--other"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnknownArgument);
- /// ```
- UnknownArgument,
-
- /// Occurs when the user provides an unrecognized [`Subcommand`] which meets the threshold for
- /// being similar enough to an existing subcommand.
- /// If it doesn't meet the threshold, or the 'suggestions' feature is disabled,
- /// the more general [`UnknownArgument`] error is returned.
- ///
- /// # Examples
- ///
- #[cfg_attr(not(feature = "suggestions"), doc = " ```no_run")]
- #[cfg_attr(feature = "suggestions", doc = " ```")]
- /// # use clap::{Command, Arg, ErrorKind, };
- /// let result = Command::new("prog")
- /// .subcommand(Command::new("config")
- /// .about("Used for configuration")
- /// .arg(Arg::new("config_file")
- /// .help("The configuration file to use")))
- /// .try_get_matches_from(vec!["prog", "confi"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidSubcommand);
- /// ```
- ///
- /// [`Subcommand`]: crate::Subcommand
- /// [`UnknownArgument`]: ErrorKind::UnknownArgument
- InvalidSubcommand,
-
- /// Occurs when the user provides an unrecognized [`Subcommand`] which either
- /// doesn't meet the threshold for being similar enough to an existing subcommand,
- /// or the 'suggestions' feature is disabled.
- /// Otherwise the more detailed [`InvalidSubcommand`] error is returned.
- ///
- /// This error typically happens when passing additional subcommand names to the `help`
- /// subcommand. Otherwise, the more general [`UnknownArgument`] error is used.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind, };
- /// let result = Command::new("prog")
- /// .subcommand(Command::new("config")
- /// .about("Used for configuration")
- /// .arg(Arg::new("config_file")
- /// .help("The configuration file to use")))
- /// .try_get_matches_from(vec!["prog", "help", "nothing"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnrecognizedSubcommand);
- /// ```
- ///
- /// [`Subcommand`]: crate::Subcommand
- /// [`InvalidSubcommand`]: ErrorKind::InvalidSubcommand
- /// [`UnknownArgument`]: ErrorKind::UnknownArgument
- UnrecognizedSubcommand,
-
- /// Occurs when the user provides an empty value for an option that does not allow empty
- /// values.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let res = Command::new("prog")
- /// .arg(Arg::new("color")
- /// .takes_value(true)
- /// .forbid_empty_values(true)
- /// .long("color"))
- /// .try_get_matches_from(vec!["prog", "--color="]);
- /// assert!(res.is_err());
- /// assert_eq!(res.unwrap_err().kind(), ErrorKind::EmptyValue);
- /// ```
- EmptyValue,
-
- /// Occurs when the user doesn't use equals for an option that requires equal
- /// sign to provide values.
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let res = Command::new("prog")
- /// .arg(Arg::new("color")
- /// .takes_value(true)
- /// .require_equals(true)
- /// .long("color"))
- /// .try_get_matches_from(vec!["prog", "--color", "red"]);
- /// assert!(res.is_err());
- /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals);
- /// ```
- NoEquals,
-
- /// Occurs when the user provides a value for an argument with a custom validation and the
- /// value fails that validation.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// fn is_numeric(val: &str) -> Result<(), String> {
- /// match val.parse::<i64>() {
- /// Ok(..) => Ok(()),
- /// Err(..) => Err(String::from("Value wasn't a number!")),
- /// }
- /// }
- ///
- /// let result = Command::new("prog")
- /// .arg(Arg::new("num")
- /// .validator(is_numeric))
- /// .try_get_matches_from(vec!["prog", "NotANumber"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ValueValidation);
- /// ```
- ValueValidation,
-
- /// Occurs when a user provides more values for an argument than were defined by setting
- /// [`Arg::max_values`].
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("arg")
- /// .max_values(2))
- /// .try_get_matches_from(vec!["prog", "too", "many", "values"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyValues);
- /// ```
- /// [`Arg::max_values`]: crate::Arg::max_values()
- TooManyValues,
-
- /// Occurs when the user provides fewer values for an argument than were defined by setting
- /// [`Arg::min_values`].
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("some_opt")
- /// .long("opt")
- /// .min_values(3))
- /// .try_get_matches_from(vec!["prog", "--opt", "too", "few"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooFewValues);
- /// ```
- /// [`Arg::min_values`]: crate::Arg::min_values()
- TooFewValues,
-
- /// Occurs when a user provides more occurrences for an argument than were defined by setting
- /// [`Arg::max_occurrences`].
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("verbosity")
- /// .short('v')
- /// .max_occurrences(2))
- /// .try_get_matches_from(vec!["prog", "-vvv"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyOccurrences);
- /// ```
- /// [`Arg::max_occurrences`]: crate::Arg::max_occurrences()
- TooManyOccurrences,
-
- /// Occurs when the user provides a different number of values for an argument than what's
- /// been defined by setting [`Arg::number_of_values`] or than was implicitly set by
- /// [`Arg::value_names`].
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("some_opt")
- /// .long("opt")
- /// .takes_value(true)
- /// .number_of_values(2))
- /// .try_get_matches_from(vec!["prog", "--opt", "wrong"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::WrongNumberOfValues);
- /// ```
- ///
- /// [`Arg::number_of_values`]: crate::Arg::number_of_values()
- /// [`Arg::value_names`]: crate::Arg::value_names()
- WrongNumberOfValues,
-
- /// Occurs when the user provides two values which conflict with each other and can't be used
- /// together.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("debug")
- /// .long("debug")
- /// .conflicts_with("color"))
- /// .arg(Arg::new("color")
- /// .long("color"))
- /// .try_get_matches_from(vec!["prog", "--debug", "--color"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ArgumentConflict);
- /// ```
- ArgumentConflict,
-
- /// Occurs when the user does not provide one or more required arguments.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("debug")
- /// .required(true))
- /// .try_get_matches_from(vec!["prog"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
- /// ```
- MissingRequiredArgument,
-
- /// Occurs when a subcommand is required (as defined by [`Command::subcommand_required`]),
- /// but the user does not provide one.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, ErrorKind};
- /// let err = Command::new("prog")
- /// .subcommand_required(true)
- /// .subcommand(Command::new("test"))
- /// .try_get_matches_from(vec![
- /// "myprog",
- /// ]);
- /// assert!(err.is_err());
- /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand);
- /// # ;
- /// ```
- ///
- /// [`Command::subcommand_required`]: crate::Command::subcommand_required
- MissingSubcommand,
-
- /// Occurs when the user provides multiple values to an argument which doesn't allow that.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .arg(Arg::new("debug")
- /// .long("debug")
- /// .multiple_occurrences(false))
- /// .try_get_matches_from(vec!["prog", "--debug", "--debug"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage);
- /// ```
- UnexpectedMultipleUsage,
-
- /// Occurs when the user provides a value containing invalid UTF-8.
- ///
- /// To allow arbitrary data
- /// - Set [`Arg::allow_invalid_utf8`] for argument values
- /// - Set [`Command::allow_invalid_utf8_for_external_subcommands`] for external-subcommand
- /// values
- ///
- /// # Platform Specific
- ///
- /// Non-Windows platforms only (such as Linux, Unix, OSX, etc.)
- ///
- /// # Examples
- ///
- #[cfg_attr(not(unix), doc = " ```ignore")]
- #[cfg_attr(unix, doc = " ```")]
- /// # use clap::{Command, Arg, ErrorKind};
- /// # use std::os::unix::ffi::OsStringExt;
- /// # use std::ffi::OsString;
- /// let result = Command::new("prog")
- /// .arg(Arg::new("utf8")
- /// .short('u')
- /// .takes_value(true))
- /// .try_get_matches_from(vec![OsString::from("myprog"),
- /// OsString::from("-u"),
- /// OsString::from_vec(vec![0xE9])]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidUtf8);
- /// ```
- ///
- /// [`Arg::allow_invalid_utf8`]: crate::Arg::allow_invalid_utf8
- /// [`Command::allow_invalid_utf8_for_external_subcommands`]: crate::Command::allow_invalid_utf8_for_external_subcommands
- InvalidUtf8,
-
- /// Not a true "error" as it means `--help` or similar was used.
- /// The help message will be sent to `stdout`.
- ///
- /// **Note**: If the help is displayed due to an error (such as missing subcommands) it will
- /// be sent to `stderr` instead of `stdout`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .try_get_matches_from(vec!["prog", "--help"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelp);
- /// ```
- DisplayHelp,
-
- /// Occurs when either an argument or a [`Subcommand`] is required, as defined by
- /// [`Command::arg_required_else_help`] , but the user did not provide
- /// one.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind, };
- /// let result = Command::new("prog")
- /// .arg_required_else_help(true)
- /// .subcommand(Command::new("config")
- /// .about("Used for configuration")
- /// .arg(Arg::new("config_file")
- /// .help("The configuration file to use")))
- /// .try_get_matches_from(vec!["prog"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand);
- /// ```
- ///
- /// [`Subcommand`]: crate::Subcommand
- /// [`Command::arg_required_else_help`]: crate::Command::arg_required_else_help
- DisplayHelpOnMissingArgumentOrSubcommand,
-
- /// Not a true "error" as it means `--version` or similar was used.
- /// The message will be sent to `stdout`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use clap::{Command, Arg, ErrorKind};
- /// let result = Command::new("prog")
- /// .version("3.0")
- /// .try_get_matches_from(vec!["prog", "--version"]);
- /// assert!(result.is_err());
- /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayVersion);
- /// ```
- DisplayVersion,
-
- /// Occurs when using the [`ArgMatches::value_of_t`] and friends 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.
- ///
- /// [`ArgMatches::value_of_t`]: crate::ArgMatches::value_of_t()
- ArgumentNotFound,
-
- /// Represents an [I/O error].
- /// Can occur when writing to `stderr` or `stdout` or reading a configuration file.
- ///
- /// [I/O error]: std::io::Error
- Io,
-
- /// Represents a [Format error] (which is a part of [`Display`]).
- /// Typically caused by writing to `stderr` or `stdout`.
- ///
- /// [`Display`]: std::fmt::Display
- /// [Format error]: std::fmt::Error
- Format,
-}
-
-impl ErrorKind {
- /// End-user description of the error case, where relevant
- pub fn as_str(self) -> Option<&'static str> {
- match self {
- Self::InvalidValue => Some("One of the values isn't valid for an argument"),
- Self::UnknownArgument => {
- Some("Found an argument which wasn't expected or isn't valid in this context")
- }
- Self::InvalidSubcommand => Some("A subcommand wasn't recognized"),
- Self::UnrecognizedSubcommand => Some("A subcommand wasn't recognized"),
- Self::EmptyValue => Some("An argument requires a value but none was supplied"),
- Self::NoEquals => Some("Equal is needed when assigning values to one of the arguments"),
- Self::ValueValidation => Some("Invalid for for one of the arguments"),
- Self::TooManyValues => Some("An argument received an unexpected value"),
- Self::TooFewValues => Some("An argument requires more values"),
- Self::TooManyOccurrences => Some("An argument occurred too many times"),
- Self::WrongNumberOfValues => Some("An argument received too many or too few values"),
- Self::ArgumentConflict => {
- Some("An argument cannot be used with one or more of the other specified arguments")
- }
- Self::MissingRequiredArgument => {
- Some("One or more required arguments were not provided")
- }
- Self::MissingSubcommand => Some("A subcommand is required but one was not provided"),
- Self::UnexpectedMultipleUsage => {
- Some("An argument was provided more than once but cannot be used multiple times")
- }
- Self::InvalidUtf8 => Some("Invalid UTF-8 was detected in one or more arguments"),
- Self::DisplayHelp => None,
- Self::DisplayHelpOnMissingArgumentOrSubcommand => None,
- Self::DisplayVersion => None,
- Self::ArgumentNotFound => Some("An argument wasn't found"),
- Self::Io => None,
- Self::Format => None,
- }
- }
-}
-
-impl std::fmt::Display for ErrorKind {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.as_str().unwrap_or_default().fmt(f)
- }
-}
diff --git a/vendor/clap/src/error/mod.rs b/vendor/clap/src/error/mod.rs
deleted file mode 100644
index df9a84c56..000000000
--- a/vendor/clap/src/error/mod.rs
+++ /dev/null
@@ -1,1158 +0,0 @@
-//! Error reporting
-#![allow(deprecated)]
-
-// Std
-use std::{
- borrow::Cow,
- convert::From,
- error,
- fmt::{self, Debug, Display, Formatter},
- io::{self, BufRead},
- result::Result as StdResult,
-};
-
-// Internal
-use crate::output::fmt::Colorizer;
-use crate::output::fmt::Stream;
-use crate::parser::features::suggestions;
-use crate::util::{color::ColorChoice, safe_exit, SUCCESS_CODE, USAGE_CODE};
-use crate::AppSettings;
-use crate::Command;
-
-mod context;
-mod kind;
-
-pub use context::ContextKind;
-pub use context::ContextValue;
-pub use kind::ErrorKind;
-
-/// Short hand for [`Result`] type
-///
-/// [`Result`]: std::result::Result
-pub type Result<T, E = Error> = StdResult<T, E>;
-
-/// Command Line Argument Parser Error
-///
-/// See [`Command::error`] to create an error.
-///
-/// [`Command::error`]: crate::Command::error
-#[derive(Debug)]
-pub struct Error {
- inner: Box<ErrorInner>,
- /// Deprecated, replaced with [`Error::kind()`]
- #[cfg_attr(
- feature = "deprecated",
- deprecated(since = "3.1.0", note = "Replaced with `Error::kind()`")
- )]
- pub kind: ErrorKind,
- /// Deprecated, replaced with [`Error::context()`]
- #[cfg_attr(
- feature = "deprecated",
- deprecated(since = "3.1.0", note = "Replaced with `Error::context()`")
- )]
- pub info: Vec<String>,
-}
-
-#[derive(Debug)]
-struct ErrorInner {
- kind: ErrorKind,
- context: Vec<(ContextKind, ContextValue)>,
- message: Option<Message>,
- source: Option<Box<dyn error::Error + Send + Sync>>,
- help_flag: Option<&'static str>,
- color_when: ColorChoice,
- wait_on_exit: bool,
- backtrace: Option<Backtrace>,
-}
-
-impl Error {
- /// Create an unformatted error
- ///
- /// This is for you need to pass the error up to
- /// a place that has access to the `Command` at which point you can call [`Error::format`].
- ///
- /// Prefer [`Command::error`] for generating errors.
- ///
- /// [`Command::error`]: crate::Command::error
- pub fn raw(kind: ErrorKind, message: impl std::fmt::Display) -> Self {
- Self::new(kind).set_message(message.to_string())
- }
-
- /// Format the existing message with the Command's context
- #[must_use]
- pub fn format(mut self, cmd: &mut Command) -> Self {
- cmd._build_self();
- let usage = cmd.render_usage();
- if let Some(message) = self.inner.message.as_mut() {
- message.format(cmd, usage);
- }
- self.with_cmd(cmd)
- }
-
- /// Type of error for programmatic processing
- pub fn kind(&self) -> ErrorKind {
- self.inner.kind
- }
-
- /// Additional information to further qualify the error
- pub fn context(&self) -> impl Iterator<Item = (ContextKind, &ContextValue)> {
- self.inner.context.iter().map(|(k, v)| (*k, v))
- }
-
- /// Should the message be written to `stdout` or not?
- #[inline]
- pub fn use_stderr(&self) -> bool {
- self.stream() == Stream::Stderr
- }
-
- pub(crate) fn stream(&self) -> Stream {
- match self.kind() {
- ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => Stream::Stdout,
- _ => Stream::Stderr,
- }
- }
-
- /// Prints the error and exits.
- ///
- /// Depending on the error kind, this either prints to `stderr` and exits with a status of `2`
- /// or prints to `stdout` and exits with a status of `0`.
- pub fn exit(&self) -> ! {
- if self.use_stderr() {
- // Swallow broken pipe errors
- let _ = self.print();
-
- if self.inner.wait_on_exit {
- wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
- let mut s = String::new();
- let i = io::stdin();
- i.lock().read_line(&mut s).unwrap();
- }
-
- safe_exit(USAGE_CODE);
- }
-
- // Swallow broken pipe errors
- let _ = self.print();
- safe_exit(SUCCESS_CODE)
- }
-
- /// Prints formatted and colored error to `stdout` or `stderr` according to its error kind
- ///
- /// # Example
- /// ```no_run
- /// use clap::Command;
- ///
- /// match Command::new("Command").try_get_matches() {
- /// Ok(matches) => {
- /// // do_something
- /// },
- /// Err(err) => {
- /// err.print().expect("Error writing Error");
- /// // do_something
- /// },
- /// };
- /// ```
- pub fn print(&self) -> io::Result<()> {
- self.formatted().print()
- }
-
- /// Deprecated, replaced with [`Command::error`]
- ///
- /// [`Command::error`]: crate::Command::error
- #[cfg_attr(
- feature = "deprecated",
- deprecated(since = "3.0.0", note = "Replaced with `Command::error`")
- )]
- #[doc(hidden)]
- pub fn with_description(description: String, kind: ErrorKind) -> Self {
- Error::raw(kind, description)
- }
-
- fn new(kind: ErrorKind) -> Self {
- Self {
- inner: Box::new(ErrorInner {
- kind,
- context: Vec::new(),
- message: None,
- source: None,
- help_flag: None,
- color_when: ColorChoice::Never,
- wait_on_exit: false,
- backtrace: Backtrace::new(),
- }),
- kind,
- info: vec![],
- }
- }
-
- #[inline(never)]
- fn for_app(kind: ErrorKind, cmd: &Command, colorizer: Colorizer, info: Vec<String>) -> Self {
- Self::new(kind)
- .set_message(colorizer)
- .with_cmd(cmd)
- .set_info(info)
- }
-
- pub(crate) fn with_cmd(self, cmd: &Command) -> Self {
- self.set_wait_on_exit(cmd.is_set(AppSettings::WaitOnError))
- .set_color(cmd.get_color())
- .set_help_flag(get_help_flag(cmd))
- }
-
- pub(crate) fn set_message(mut self, message: impl Into<Message>) -> Self {
- self.inner.message = Some(message.into());
- self
- }
-
- pub(crate) fn set_info(mut self, info: Vec<String>) -> Self {
- self.info = info;
- self
- }
-
- pub(crate) fn set_source(mut self, source: Box<dyn error::Error + Send + Sync>) -> Self {
- self.inner.source = Some(source);
- self
- }
-
- pub(crate) fn set_color(mut self, color_when: ColorChoice) -> Self {
- self.inner.color_when = color_when;
- self
- }
-
- pub(crate) fn set_help_flag(mut self, help_flag: Option<&'static str>) -> Self {
- self.inner.help_flag = help_flag;
- self
- }
-
- pub(crate) fn set_wait_on_exit(mut self, yes: bool) -> Self {
- self.inner.wait_on_exit = yes;
- self
- }
-
- /// Does not verify if `ContextKind` is already present
- #[inline(never)]
- pub(crate) fn insert_context_unchecked(
- mut self,
- kind: ContextKind,
- value: ContextValue,
- ) -> Self {
- self.inner.context.push((kind, value));
- self
- }
-
- /// Does not verify if `ContextKind` is already present
- #[inline(never)]
- pub(crate) fn extend_context_unchecked<const N: usize>(
- mut self,
- context: [(ContextKind, ContextValue); N],
- ) -> Self {
- self.inner.context.extend(context);
- self
- }
-
- #[inline(never)]
- fn get_context(&self, kind: ContextKind) -> Option<&ContextValue> {
- self.inner
- .context
- .iter()
- .find_map(|(k, v)| (*k == kind).then(|| v))
- }
-
- pub(crate) fn display_help(cmd: &Command, colorizer: Colorizer) -> Self {
- Self::for_app(ErrorKind::DisplayHelp, cmd, colorizer, vec![])
- }
-
- pub(crate) fn display_help_error(cmd: &Command, colorizer: Colorizer) -> Self {
- Self::for_app(
- ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand,
- cmd,
- colorizer,
- vec![],
- )
- }
-
- pub(crate) fn display_version(cmd: &Command, colorizer: Colorizer) -> Self {
- Self::for_app(ErrorKind::DisplayVersion, cmd, colorizer, vec![])
- }
-
- pub(crate) fn argument_conflict(
- cmd: &Command,
- arg: String,
- mut others: Vec<String>,
- usage: String,
- ) -> Self {
- let info = others.clone();
- let others = match others.len() {
- 0 => ContextValue::None,
- 1 => ContextValue::String(others.pop().unwrap()),
- _ => ContextValue::Strings(others),
- };
- Self::new(ErrorKind::ArgumentConflict)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::PriorArg, others),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn empty_value(cmd: &Command, good_vals: &[&str], arg: String) -> Self {
- let info = vec![arg.clone()];
- let mut err = Self::new(ErrorKind::EmptyValue)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]);
- if !good_vals.is_empty() {
- err = err.insert_context_unchecked(
- ContextKind::ValidValue,
- ContextValue::Strings(good_vals.iter().map(|s| (*s).to_owned()).collect()),
- );
- }
- err
- }
-
- pub(crate) fn no_equals(cmd: &Command, arg: String, usage: String) -> Self {
- let info = vec![arg.clone()];
- Self::new(ErrorKind::NoEquals)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn invalid_value(
- cmd: &Command,
- bad_val: String,
- good_vals: &[&str],
- arg: String,
- ) -> Self {
- let mut info = vec![arg.clone(), bad_val.clone()];
- info.extend(good_vals.iter().map(|s| (*s).to_owned()));
-
- let suggestion = suggestions::did_you_mean(&bad_val, good_vals.iter()).pop();
- let mut err = Self::new(ErrorKind::InvalidValue)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::InvalidValue, ContextValue::String(bad_val)),
- (
- ContextKind::ValidValue,
- ContextValue::Strings(good_vals.iter().map(|s| (*s).to_owned()).collect()),
- ),
- ]);
- if let Some(suggestion) = suggestion {
- err = err.insert_context_unchecked(
- ContextKind::SuggestedValue,
- ContextValue::String(suggestion),
- );
- }
- err
- }
-
- pub(crate) fn invalid_subcommand(
- cmd: &Command,
- subcmd: String,
- did_you_mean: String,
- name: String,
- usage: String,
- ) -> Self {
- let info = vec![subcmd.clone()];
- let suggestion = format!("{} -- {}", name, subcmd);
- Self::new(ErrorKind::InvalidSubcommand)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidSubcommand, ContextValue::String(subcmd)),
- (
- ContextKind::SuggestedSubcommand,
- ContextValue::String(did_you_mean),
- ),
- (
- ContextKind::SuggestedCommand,
- ContextValue::String(suggestion),
- ),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn unrecognized_subcommand(cmd: &Command, subcmd: String, usage: String) -> Self {
- let info = vec![subcmd.clone()];
- Self::new(ErrorKind::UnrecognizedSubcommand)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidSubcommand, ContextValue::String(subcmd)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn missing_required_argument(
- cmd: &Command,
- required: Vec<String>,
- usage: String,
- ) -> Self {
- let info = required.clone();
- Self::new(ErrorKind::MissingRequiredArgument)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::Strings(required)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn missing_subcommand(cmd: &Command, name: String, usage: String) -> Self {
- let info = vec![];
- Self::new(ErrorKind::MissingSubcommand)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidSubcommand, ContextValue::String(name)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn invalid_utf8(cmd: &Command, usage: String) -> Self {
- let info = vec![];
- Self::new(ErrorKind::InvalidUtf8)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([(ContextKind::Usage, ContextValue::String(usage))])
- }
-
- pub(crate) fn too_many_occurrences(
- cmd: &Command,
- arg: String,
- max_occurs: usize,
- curr_occurs: usize,
- usage: String,
- ) -> Self {
- let info = vec![arg.clone(), curr_occurs.to_string(), max_occurs.to_string()];
- Self::new(ErrorKind::TooManyOccurrences)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (
- ContextKind::MaxOccurrences,
- ContextValue::Number(max_occurs as isize),
- ),
- (
- ContextKind::ActualNumValues,
- ContextValue::Number(curr_occurs as isize),
- ),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn too_many_values(cmd: &Command, val: String, arg: String, usage: String) -> Self {
- let info = vec![arg.clone(), val.clone()];
- Self::new(ErrorKind::TooManyValues)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::InvalidValue, ContextValue::String(val)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn too_few_values(
- cmd: &Command,
- arg: String,
- min_vals: usize,
- curr_vals: usize,
- usage: String,
- ) -> Self {
- let info = vec![arg.clone(), curr_vals.to_string(), min_vals.to_string()];
- Self::new(ErrorKind::TooFewValues)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (
- ContextKind::MinValues,
- ContextValue::Number(min_vals as isize),
- ),
- (
- ContextKind::ActualNumValues,
- ContextValue::Number(curr_vals as isize),
- ),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn value_validation(
- arg: String,
- val: String,
- err: Box<dyn error::Error + Send + Sync>,
- ) -> Self {
- let info = vec![arg.clone(), val.to_string(), err.to_string()];
- Self::new(ErrorKind::ValueValidation)
- .set_info(info)
- .set_source(err)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::InvalidValue, ContextValue::String(val)),
- ])
- }
-
- pub(crate) fn wrong_number_of_values(
- cmd: &Command,
- arg: String,
- num_vals: usize,
- curr_vals: usize,
- usage: String,
- ) -> Self {
- let info = vec![arg.clone(), curr_vals.to_string(), num_vals.to_string()];
- Self::new(ErrorKind::WrongNumberOfValues)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (
- ContextKind::ExpectedNumValues,
- ContextValue::Number(num_vals as isize),
- ),
- (
- ContextKind::ActualNumValues,
- ContextValue::Number(curr_vals as isize),
- ),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn unexpected_multiple_usage(cmd: &Command, arg: String, usage: String) -> Self {
- let info = vec![arg.clone()];
- Self::new(ErrorKind::UnexpectedMultipleUsage)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn unknown_argument(
- cmd: &Command,
- arg: String,
- did_you_mean: Option<(String, Option<String>)>,
- usage: String,
- ) -> Self {
- let info = vec![arg.clone()];
- let mut err = Self::new(ErrorKind::UnknownArgument)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ]);
- if let Some((flag, sub)) = did_you_mean {
- err = err.insert_context_unchecked(
- ContextKind::SuggestedArg,
- ContextValue::String(format!("--{}", flag)),
- );
- if let Some(sub) = sub {
- err = err.insert_context_unchecked(
- ContextKind::SuggestedSubcommand,
- ContextValue::String(sub),
- );
- }
- }
- err
- }
-
- pub(crate) fn unnecessary_double_dash(cmd: &Command, arg: String, usage: String) -> Self {
- let info = vec![arg.clone()];
- Self::new(ErrorKind::UnknownArgument)
- .with_cmd(cmd)
- .set_info(info)
- .extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::TrailingArg, ContextValue::Bool(true)),
- (ContextKind::Usage, ContextValue::String(usage)),
- ])
- }
-
- pub(crate) fn argument_not_found_auto(arg: String) -> Self {
- let info = vec![arg.clone()];
- Self::new(ErrorKind::ArgumentNotFound)
- .set_info(info)
- .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))])
- }
-
- fn formatted(&self) -> Cow<'_, Colorizer> {
- if let Some(message) = self.inner.message.as_ref() {
- message.formatted()
- } else {
- let mut c = Colorizer::new(self.stream(), self.inner.color_when);
-
- start_error(&mut c);
-
- if !self.write_dynamic_context(&mut c) {
- if let Some(msg) = self.kind().as_str() {
- c.none(msg.to_owned());
- } else if let Some(source) = self.inner.source.as_ref() {
- c.none(source.to_string());
- } else {
- c.none("Unknown cause");
- }
- }
-
- let usage = self.get_context(ContextKind::Usage);
- if let Some(ContextValue::String(usage)) = usage {
- put_usage(&mut c, usage);
- }
-
- try_help(&mut c, self.inner.help_flag);
-
- Cow::Owned(c)
- }
- }
-
- #[must_use]
- fn write_dynamic_context(&self, c: &mut Colorizer) -> bool {
- match self.kind() {
- ErrorKind::ArgumentConflict => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- let prior_arg = self.get_context(ContextKind::PriorArg);
- if let (Some(ContextValue::String(invalid_arg)), Some(prior_arg)) =
- (invalid_arg, prior_arg)
- {
- c.none("The argument '");
- c.warning(invalid_arg);
- c.none("' cannot be used with");
-
- match prior_arg {
- ContextValue::Strings(values) => {
- c.none(":");
- for v in values {
- c.none("\n ");
- c.warning(&**v);
- }
- }
- ContextValue::String(value) => {
- c.none(" '");
- c.warning(value);
- c.none("'");
- }
- _ => {
- c.none(" one or more of the other specified arguments");
- }
- }
- true
- } else {
- false
- }
- }
- ErrorKind::EmptyValue => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- c.none("The argument '");
- c.warning(invalid_arg);
- c.none("' requires a value but none was supplied");
-
- let possible_values = self.get_context(ContextKind::ValidValue);
- if let Some(ContextValue::Strings(possible_values)) = possible_values {
- c.none("\n\t[possible values: ");
- if let Some((last, elements)) = possible_values.split_last() {
- for v in elements {
- c.good(escape(v));
- c.none(", ");
- }
- c.good(escape(last));
- }
- c.none("]");
- }
- true
- } else {
- false
- }
- }
- ErrorKind::NoEquals => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- c.none("Equal sign is needed when assigning values to '");
- c.warning(invalid_arg);
- c.none("'.");
- true
- } else {
- false
- }
- }
- ErrorKind::InvalidValue => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- let invalid_value = self.get_context(ContextKind::InvalidValue);
- if let (
- Some(ContextValue::String(invalid_arg)),
- Some(ContextValue::String(invalid_value)),
- ) = (invalid_arg, invalid_value)
- {
- c.none(quote(invalid_value));
- c.none(" isn't a valid value for '");
- c.warning(invalid_arg);
- c.none("'");
-
- let possible_values = self.get_context(ContextKind::ValidValue);
- if let Some(ContextValue::Strings(possible_values)) = possible_values {
- c.none("\n\t[possible values: ");
- if let Some((last, elements)) = possible_values.split_last() {
- for v in elements {
- c.good(escape(v));
- c.none(", ");
- }
- c.good(escape(last));
- }
- c.none("]");
- }
-
- let suggestion = self.get_context(ContextKind::SuggestedValue);
- if let Some(ContextValue::String(suggestion)) = suggestion {
- c.none("\n\n\tDid you mean ");
- c.good(quote(suggestion));
- c.none("?");
- }
- true
- } else {
- false
- }
- }
- ErrorKind::InvalidSubcommand => {
- let invalid_sub = self.get_context(ContextKind::InvalidSubcommand);
- if let Some(ContextValue::String(invalid_sub)) = invalid_sub {
- c.none("The subcommand '");
- c.warning(invalid_sub);
- c.none("' wasn't recognized");
-
- let valid_sub = self.get_context(ContextKind::SuggestedSubcommand);
- if let Some(ContextValue::String(valid_sub)) = valid_sub {
- c.none("\n\n\tDid you mean ");
- c.good(valid_sub);
- c.none("?");
- }
-
- let suggestion = self.get_context(ContextKind::SuggestedCommand);
- if let Some(ContextValue::String(suggestion)) = suggestion {
- c.none(
- "\n\nIf you believe you received this message in error, try re-running with '",
- );
- c.good(suggestion);
- c.none("'");
- }
- true
- } else {
- false
- }
- }
- ErrorKind::UnrecognizedSubcommand => {
- let invalid_sub = self.get_context(ContextKind::InvalidSubcommand);
- if let Some(ContextValue::String(invalid_sub)) = invalid_sub {
- c.none("The subcommand '");
- c.warning(invalid_sub);
- c.none("' wasn't recognized");
- true
- } else {
- false
- }
- }
- ErrorKind::MissingRequiredArgument => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- if let Some(ContextValue::Strings(invalid_arg)) = invalid_arg {
- c.none("The following required arguments were not provided:");
- for v in invalid_arg {
- c.none("\n ");
- c.good(&**v);
- }
- true
- } else {
- false
- }
- }
- ErrorKind::MissingSubcommand => {
- let invalid_sub = self.get_context(ContextKind::InvalidSubcommand);
- if let Some(ContextValue::String(invalid_sub)) = invalid_sub {
- c.none("'");
- c.warning(invalid_sub);
- c.none("' requires a subcommand but one was not provided");
- true
- } else {
- false
- }
- }
- ErrorKind::InvalidUtf8 => false,
- ErrorKind::TooManyOccurrences => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- let actual_num_occurs = self.get_context(ContextKind::ActualNumOccurrences);
- let max_occurs = self.get_context(ContextKind::MaxOccurrences);
- if let (
- Some(ContextValue::String(invalid_arg)),
- Some(ContextValue::Number(actual_num_occurs)),
- Some(ContextValue::Number(max_occurs)),
- ) = (invalid_arg, actual_num_occurs, max_occurs)
- {
- let were_provided = Error::singular_or_plural(*actual_num_occurs as usize);
- c.none("The argument '");
- c.warning(invalid_arg);
- c.none("' allows at most ");
- c.warning(max_occurs.to_string());
- c.none(" occurrences but ");
- c.warning(actual_num_occurs.to_string());
- c.none(were_provided);
- true
- } else {
- false
- }
- }
- ErrorKind::TooManyValues => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- let invalid_value = self.get_context(ContextKind::InvalidValue);
- if let (
- Some(ContextValue::String(invalid_arg)),
- Some(ContextValue::String(invalid_value)),
- ) = (invalid_arg, invalid_value)
- {
- c.none("The value '");
- c.warning(invalid_value);
- c.none("' was provided to '");
- c.warning(invalid_arg);
- c.none("' but it wasn't expecting any more values");
- true
- } else {
- false
- }
- }
- ErrorKind::TooFewValues => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- let actual_num_values = self.get_context(ContextKind::ActualNumValues);
- let min_values = self.get_context(ContextKind::MinValues);
- if let (
- Some(ContextValue::String(invalid_arg)),
- Some(ContextValue::Number(actual_num_values)),
- Some(ContextValue::Number(min_values)),
- ) = (invalid_arg, actual_num_values, min_values)
- {
- let were_provided = Error::singular_or_plural(*actual_num_values as usize);
- c.none("The argument '");
- c.warning(invalid_arg);
- c.none("' requires at least ");
- c.warning(min_values.to_string());
- c.none(" values but only ");
- c.warning(actual_num_values.to_string());
- c.none(were_provided);
- true
- } else {
- false
- }
- }
- ErrorKind::ValueValidation => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- let invalid_value = self.get_context(ContextKind::InvalidValue);
- if let (
- Some(ContextValue::String(invalid_arg)),
- Some(ContextValue::String(invalid_value)),
- ) = (invalid_arg, invalid_value)
- {
- c.none("Invalid value ");
- c.warning(quote(invalid_value));
- c.none(" for '");
- c.warning(invalid_arg);
- if let Some(source) = self.inner.source.as_deref() {
- c.none("': ");
- c.none(source.to_string());
- } else {
- c.none("'");
- }
- true
- } else {
- false
- }
- }
- ErrorKind::WrongNumberOfValues => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- let actual_num_values = self.get_context(ContextKind::ActualNumValues);
- let num_values = self.get_context(ContextKind::ExpectedNumValues);
- if let (
- Some(ContextValue::String(invalid_arg)),
- Some(ContextValue::Number(actual_num_values)),
- Some(ContextValue::Number(num_values)),
- ) = (invalid_arg, actual_num_values, num_values)
- {
- let were_provided = Error::singular_or_plural(*actual_num_values as usize);
- c.none("The argument '");
- c.warning(invalid_arg);
- c.none("' requires ");
- c.warning(num_values.to_string());
- c.none(" values, but ");
- c.warning(actual_num_values.to_string());
- c.none(were_provided);
- true
- } else {
- false
- }
- }
- ErrorKind::UnexpectedMultipleUsage => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- c.none("The argument '");
- c.warning(invalid_arg.to_string());
- c.none("' was provided more than once, but cannot be used multiple times");
- true
- } else {
- false
- }
- }
- ErrorKind::UnknownArgument => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- c.none("Found argument '");
- c.warning(invalid_arg.to_string());
- c.none("' which wasn't expected, or isn't valid in this context");
-
- let valid_sub = self.get_context(ContextKind::SuggestedSubcommand);
- let valid_arg = self.get_context(ContextKind::SuggestedArg);
- match (valid_sub, valid_arg) {
- (
- Some(ContextValue::String(valid_sub)),
- Some(ContextValue::String(valid_arg)),
- ) => {
- c.none("\n\n\tDid you mean ");
- c.none("to put '");
- c.good(valid_arg);
- c.none("' after the subcommand '");
- c.good(valid_sub);
- c.none("'?");
- }
- (None, Some(ContextValue::String(valid_arg))) => {
- c.none("\n\n\tDid you mean '");
- c.good(valid_arg);
- c.none("'?");
- }
- (_, _) => {}
- }
-
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- if invalid_arg.starts_with('-') {
- c.none(format!(
- "\n\n\tIf you tried to supply `{}` as a value rather than a flag, use `-- {}`",
- invalid_arg, invalid_arg
- ));
- }
-
- let trailing_arg = self.get_context(ContextKind::TrailingArg);
- if trailing_arg == Some(&ContextValue::Bool(true)) {
- c.none(format!(
- "\n\n\tIf you tried to supply `{}` as a subcommand, remove the '--' before it.",
- invalid_arg
- ));
- }
- }
- true
- } else {
- false
- }
- }
- ErrorKind::ArgumentNotFound => {
- let invalid_arg = self.get_context(ContextKind::InvalidArg);
- if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- c.none("The argument '");
- c.warning(invalid_arg.to_string());
- c.none("' wasn't found");
- true
- } else {
- false
- }
- }
- ErrorKind::DisplayHelp
- | ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
- | ErrorKind::DisplayVersion
- | ErrorKind::Io
- | ErrorKind::Format => false,
- }
- }
-
- /// Returns the singular or plural form on the verb to be based on the argument's value.
- fn singular_or_plural(n: usize) -> &'static str {
- if n > 1 {
- " were provided"
- } else {
- " was provided"
- }
- }
-}
-
-impl From<io::Error> for Error {
- fn from(e: io::Error) -> Self {
- Error::raw(ErrorKind::Io, e)
- }
-}
-
-impl From<fmt::Error> for Error {
- fn from(e: fmt::Error) -> Self {
- Error::raw(ErrorKind::Format, e)
- }
-}
-
-impl error::Error for Error {
- #[allow(trivial_casts)]
- fn source(&self) -> Option<&(dyn error::Error + 'static)> {
- self.inner.source.as_ref().map(|e| e.as_ref() as _)
- }
-}
-
-impl Display for Error {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- // Assuming `self.message` already has a trailing newline, from `try_help` or similar
- write!(f, "{}", self.formatted())?;
- if let Some(backtrace) = self.inner.backtrace.as_ref() {
- writeln!(f)?;
- writeln!(f, "Backtrace:")?;
- writeln!(f, "{}", backtrace)?;
- }
- Ok(())
- }
-}
-
-fn start_error(c: &mut Colorizer) {
- c.error("error:");
- c.none(" ");
-}
-
-fn put_usage(c: &mut Colorizer, usage: impl Into<String>) {
- c.none("\n\n");
- c.none(usage);
-}
-
-fn get_help_flag(cmd: &Command) -> Option<&'static str> {
- if !cmd.is_disable_help_flag_set() {
- Some("--help")
- } else if cmd.has_subcommands() && !cmd.is_disable_help_subcommand_set() {
- Some("help")
- } else {
- None
- }
-}
-
-fn try_help(c: &mut Colorizer, help: Option<&str>) {
- if let Some(help) = help {
- c.none("\n\nFor more information try ");
- c.good(help);
- c.none("\n");
- } else {
- c.none("\n");
- }
-}
-
-fn quote(s: impl AsRef<str>) -> String {
- let s = s.as_ref();
- format!("{:?}", s)
-}
-
-fn escape(s: impl AsRef<str>) -> String {
- let s = s.as_ref();
- if s.contains(char::is_whitespace) {
- quote(s)
- } else {
- s.to_owned()
- }
-}
-
-#[derive(Clone, Debug)]
-pub(crate) enum Message {
- Raw(String),
- Formatted(Colorizer),
-}
-
-impl Message {
- fn format(&mut self, cmd: &Command, usage: String) {
- match self {
- Message::Raw(s) => {
- let mut c = Colorizer::new(Stream::Stderr, cmd.get_color());
-
- let mut message = String::new();
- std::mem::swap(s, &mut message);
- start_error(&mut c);
- c.none(message);
- put_usage(&mut c, usage);
- try_help(&mut c, get_help_flag(cmd));
- *self = Self::Formatted(c);
- }
- Message::Formatted(_) => {}
- }
- }
-
- fn formatted(&self) -> Cow<Colorizer> {
- match self {
- Message::Raw(s) => {
- let mut c = Colorizer::new(Stream::Stderr, ColorChoice::Never);
- start_error(&mut c);
- c.none(s);
- Cow::Owned(c)
- }
- Message::Formatted(c) => Cow::Borrowed(c),
- }
- }
-}
-
-impl From<String> for Message {
- fn from(inner: String) -> Self {
- Self::Raw(inner)
- }
-}
-
-impl From<Colorizer> for Message {
- fn from(inner: Colorizer) -> Self {
- Self::Formatted(inner)
- }
-}
-
-#[cfg(feature = "debug")]
-#[derive(Debug)]
-struct Backtrace(backtrace::Backtrace);
-
-#[cfg(feature = "debug")]
-impl Backtrace {
- fn new() -> Option<Self> {
- Some(Self(backtrace::Backtrace::new()))
- }
-}
-
-#[cfg(feature = "debug")]
-impl Display for Backtrace {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- // `backtrace::Backtrace` uses `Debug` instead of `Display`
- write!(f, "{:?}", self.0)
- }
-}
-
-#[cfg(not(feature = "debug"))]
-#[derive(Debug)]
-struct Backtrace;
-
-#[cfg(not(feature = "debug"))]
-impl Backtrace {
- fn new() -> Option<Self> {
- None
- }
-}
-
-#[cfg(not(feature = "debug"))]
-impl Display for Backtrace {
- fn fmt(&self, _: &mut Formatter) -> fmt::Result {
- Ok(())
- }
-}
-
-#[cfg(test)]
-mod tests {
- /// Check `clap::Error` impls Send and Sync.
- mod clap_error_impl_send_sync {
- use crate::Error;
- trait Foo: std::error::Error + Send + Sync + 'static {}
- impl Foo for Error {}
- }
-}