diff options
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.rs | 440 | ||||
-rw-r--r-- | vendor/clap/src/error/mod.rs | 1158 |
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 {} - } -} |