summaryrefslogtreecommitdiffstats
path: root/vendor/clap/src/error/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vendor/clap/src/error/mod.rs1158
1 files changed, 0 insertions, 1158 deletions
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 {}
- }
-}