aboutsummaryrefslogtreecommitdiff
path: root/vendor/clap_builder/src/error/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/clap_builder/src/error/mod.rs')
-rw-r--r--vendor/clap_builder/src/error/mod.rs923
1 files changed, 0 insertions, 923 deletions
diff --git a/vendor/clap_builder/src/error/mod.rs b/vendor/clap_builder/src/error/mod.rs
deleted file mode 100644
index af90e27..0000000
--- a/vendor/clap_builder/src/error/mod.rs
+++ /dev/null
@@ -1,923 +0,0 @@
-//! Error reporting
-
-#![cfg_attr(not(feature = "error-context"), allow(dead_code))]
-#![cfg_attr(not(feature = "error-context"), allow(unused_imports))]
-#![cfg_attr(not(feature = "error-context"), allow(unused_variables))]
-#![cfg_attr(not(feature = "error-context"), allow(unused_mut))]
-#![cfg_attr(not(feature = "error-context"), allow(clippy::let_and_return))]
-
-// Std
-use std::{
- borrow::Cow,
- convert::From,
- error,
- fmt::{self, Debug, Display, Formatter},
- io::{self},
- result::Result as StdResult,
-};
-
-// Internal
-use crate::builder::StyledStr;
-use crate::builder::Styles;
-use crate::output::fmt::Colorizer;
-use crate::output::fmt::Stream;
-use crate::parser::features::suggestions;
-use crate::util::FlatMap;
-use crate::util::{color::ColorChoice, safe_exit, SUCCESS_CODE, USAGE_CODE};
-use crate::Command;
-
-#[cfg(feature = "error-context")]
-mod context;
-mod format;
-mod kind;
-
-pub use format::ErrorFormatter;
-pub use format::KindFormatter;
-pub use kind::ErrorKind;
-
-#[cfg(feature = "error-context")]
-pub use context::ContextKind;
-#[cfg(feature = "error-context")]
-pub use context::ContextValue;
-#[cfg(feature = "error-context")]
-pub use format::RichFormatter;
-
-#[cfg(not(feature = "error-context"))]
-pub use KindFormatter as DefaultFormatter;
-#[cfg(feature = "error-context")]
-pub use RichFormatter as DefaultFormatter;
-
-/// 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
-pub struct Error<F: ErrorFormatter = DefaultFormatter> {
- inner: Box<ErrorInner>,
- phantom: std::marker::PhantomData<F>,
-}
-
-#[derive(Debug)]
-struct ErrorInner {
- kind: ErrorKind,
- #[cfg(feature = "error-context")]
- context: FlatMap<ContextKind, ContextValue>,
- message: Option<Message>,
- source: Option<Box<dyn error::Error + Send + Sync>>,
- help_flag: Option<&'static str>,
- styles: Styles,
- color_when: ColorChoice,
- color_help_when: ColorChoice,
- backtrace: Option<Backtrace>,
-}
-
-impl<F: ErrorFormatter> Error<F> {
- /// 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(false);
- let usage = cmd.render_usage_();
- if let Some(message) = self.inner.message.as_mut() {
- message.format(cmd, usage);
- }
- self.with_cmd(cmd)
- }
-
- /// Create an error with a pre-defined message
- ///
- /// See also
- /// - [`Error::insert`]
- /// - [`Error::with_cmd`]
- ///
- /// # Example
- ///
- /// ```rust
- /// # #[cfg(feature = "error-context")] {
- /// # use clap_builder as clap;
- /// # use clap::error::ErrorKind;
- /// # use clap::error::ContextKind;
- /// # use clap::error::ContextValue;
- ///
- /// let cmd = clap::Command::new("prog");
- ///
- /// let mut err = clap::Error::new(ErrorKind::ValueValidation)
- /// .with_cmd(&cmd);
- /// err.insert(ContextKind::InvalidArg, ContextValue::String("--foo".to_owned()));
- /// err.insert(ContextKind::InvalidValue, ContextValue::String("bar".to_owned()));
- ///
- /// err.print();
- /// # }
- /// ```
- pub fn new(kind: ErrorKind) -> Self {
- Self {
- inner: Box::new(ErrorInner {
- kind,
- #[cfg(feature = "error-context")]
- context: FlatMap::new(),
- message: None,
- source: None,
- help_flag: None,
- styles: Styles::plain(),
- color_when: ColorChoice::Never,
- color_help_when: ColorChoice::Never,
- backtrace: Backtrace::new(),
- }),
- phantom: Default::default(),
- }
- }
-
- /// Apply [`Command`]'s formatting to the error
- ///
- /// Generally, this is used with [`Error::new`]
- pub fn with_cmd(self, cmd: &Command) -> Self {
- self.set_styles(cmd.get_styles().clone())
- .set_color(cmd.get_color())
- .set_colored_help(cmd.color_help())
- .set_help_flag(format::get_help_flag(cmd))
- }
-
- /// Apply an alternative formatter to the error
- ///
- /// # Example
- ///
- /// ```rust
- /// # use clap_builder as clap;
- /// # use clap::Command;
- /// # use clap::Arg;
- /// # use clap::error::KindFormatter;
- /// let cmd = Command::new("foo")
- /// .arg(Arg::new("input").required(true));
- /// let matches = cmd
- /// .try_get_matches_from(["foo", "input.txt"])
- /// .map_err(|e| e.apply::<KindFormatter>())
- /// .unwrap_or_else(|e| e.exit());
- /// ```
- pub fn apply<EF: ErrorFormatter>(self) -> Error<EF> {
- Error {
- inner: self.inner,
- phantom: Default::default(),
- }
- }
-
- /// Type of error for programmatic processing
- pub fn kind(&self) -> ErrorKind {
- self.inner.kind
- }
-
- /// Additional information to further qualify the error
- #[cfg(feature = "error-context")]
- pub fn context(&self) -> impl Iterator<Item = (ContextKind, &ContextValue)> {
- self.inner.context.iter().map(|(k, v)| (*k, v))
- }
-
- /// Lookup a piece of context
- #[inline(never)]
- #[cfg(feature = "error-context")]
- pub fn get(&self, kind: ContextKind) -> Option<&ContextValue> {
- self.inner.context.get(&kind)
- }
-
- /// Insert a piece of context
- #[inline(never)]
- #[cfg(feature = "error-context")]
- pub fn insert(&mut self, kind: ContextKind, value: ContextValue) -> Option<ContextValue> {
- self.inner.context.insert(kind, value)
- }
-
- /// 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,
- }
- }
-
- /// Returns the exit code that `.exit` will exit the process with.
- ///
- /// When the error's kind would print to `stderr` this returns `2`,
- /// else it returns `0`.
- pub fn exit_code(&self) -> i32 {
- if self.use_stderr() {
- USAGE_CODE
- } else {
- SUCCESS_CODE
- }
- }
-
- /// 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) -> ! {
- // Swallow broken pipe errors
- let _ = self.print();
- safe_exit(self.exit_code())
- }
-
- /// Prints formatted and colored error to `stdout` or `stderr` according to its error kind
- ///
- /// # Example
- /// ```no_run
- /// # use clap_builder as clap;
- /// 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<()> {
- let style = self.formatted();
- let color_when = if matches!(
- self.kind(),
- ErrorKind::DisplayHelp | ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand,
- ) {
- self.inner.color_help_when
- } else {
- self.inner.color_when
- };
- let c = Colorizer::new(self.stream(), color_when).with_content(style.into_owned());
- c.print()
- }
-
- /// Render the error message to a [`StyledStr`].
- ///
- /// # Example
- /// ```no_run
- /// # use clap_builder as clap;
- /// use clap::Command;
- ///
- /// match Command::new("Command").try_get_matches() {
- /// Ok(matches) => {
- /// // do_something
- /// },
- /// Err(err) => {
- /// let err = err.render();
- /// println!("{err}");
- /// // do_something
- /// },
- /// };
- /// ```
- pub fn render(&self) -> StyledStr {
- self.formatted().into_owned()
- }
-
- #[inline(never)]
- fn for_app(kind: ErrorKind, cmd: &Command, styled: StyledStr) -> Self {
- Self::new(kind).set_message(styled).with_cmd(cmd)
- }
-
- pub(crate) fn set_message(mut self, message: impl Into<Message>) -> Self {
- self.inner.message = Some(message.into());
- 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_styles(mut self, styles: Styles) -> Self {
- self.inner.styles = styles;
- self
- }
-
- pub(crate) fn set_color(mut self, color_when: ColorChoice) -> Self {
- self.inner.color_when = color_when;
- self
- }
-
- pub(crate) fn set_colored_help(mut self, color_help_when: ColorChoice) -> Self {
- self.inner.color_help_when = color_help_when;
- self
- }
-
- pub(crate) fn set_help_flag(mut self, help_flag: Option<&'static str>) -> Self {
- self.inner.help_flag = help_flag;
- self
- }
-
- /// Does not verify if `ContextKind` is already present
- #[inline(never)]
- #[cfg(feature = "error-context")]
- pub(crate) fn insert_context_unchecked(
- mut self,
- kind: ContextKind,
- value: ContextValue,
- ) -> Self {
- self.inner.context.insert_unchecked(kind, value);
- self
- }
-
- /// Does not verify if `ContextKind` is already present
- #[inline(never)]
- #[cfg(feature = "error-context")]
- pub(crate) fn extend_context_unchecked<const N: usize>(
- mut self,
- context: [(ContextKind, ContextValue); N],
- ) -> Self {
- self.inner.context.extend_unchecked(context);
- self
- }
-
- pub(crate) fn display_help(cmd: &Command, styled: StyledStr) -> Self {
- Self::for_app(ErrorKind::DisplayHelp, cmd, styled)
- }
-
- pub(crate) fn display_help_error(cmd: &Command, styled: StyledStr) -> Self {
- Self::for_app(
- ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand,
- cmd,
- styled,
- )
- }
-
- pub(crate) fn display_version(cmd: &Command, styled: StyledStr) -> Self {
- Self::for_app(ErrorKind::DisplayVersion, cmd, styled)
- }
-
- pub(crate) fn argument_conflict(
- cmd: &Command,
- arg: String,
- mut others: Vec<String>,
- usage: Option<StyledStr>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::ArgumentConflict).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- let others = match others.len() {
- 0 => ContextValue::None,
- 1 => ContextValue::String(others.pop().unwrap()),
- _ => ContextValue::Strings(others),
- };
- err = err.extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::PriorArg, others),
- ]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn empty_value(cmd: &Command, good_vals: &[String], arg: String) -> Self {
- Self::invalid_value(cmd, "".to_owned(), good_vals, arg)
- }
-
- pub(crate) fn no_equals(cmd: &Command, arg: String, usage: Option<StyledStr>) -> Self {
- let mut err = Self::new(ErrorKind::NoEquals).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err
- .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn invalid_value(
- cmd: &Command,
- bad_val: String,
- good_vals: &[String],
- arg: String,
- ) -> Self {
- let suggestion = suggestions::did_you_mean(&bad_val, good_vals.iter()).pop();
- let mut err = Self::new(ErrorKind::InvalidValue).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err.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: Vec<String>,
- name: String,
- suggested_trailing_arg: bool,
- usage: Option<StyledStr>,
- ) -> Self {
- use std::fmt::Write as _;
- let styles = cmd.get_styles();
- let invalid = &styles.get_invalid();
- let valid = &styles.get_valid();
- let mut err = Self::new(ErrorKind::InvalidSubcommand).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- let mut suggestions = vec![];
- if suggested_trailing_arg {
- let mut styled_suggestion = StyledStr::new();
- let _ = write!(
- styled_suggestion,
- "to pass '{}{subcmd}{}' as a value, use '{}{name} -- {subcmd}{}'",
- invalid.render(),
- invalid.render_reset(),
- valid.render(),
- valid.render_reset()
- );
- suggestions.push(styled_suggestion);
- }
-
- err = err.extend_context_unchecked([
- (ContextKind::InvalidSubcommand, ContextValue::String(subcmd)),
- (
- ContextKind::SuggestedSubcommand,
- ContextValue::Strings(did_you_mean),
- ),
- (
- ContextKind::Suggested,
- ContextValue::StyledStrs(suggestions),
- ),
- ]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn unrecognized_subcommand(
- cmd: &Command,
- subcmd: String,
- usage: Option<StyledStr>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::InvalidSubcommand).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err.extend_context_unchecked([(
- ContextKind::InvalidSubcommand,
- ContextValue::String(subcmd),
- )]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn missing_required_argument(
- cmd: &Command,
- required: Vec<String>,
- usage: Option<StyledStr>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::MissingRequiredArgument).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err.extend_context_unchecked([(
- ContextKind::InvalidArg,
- ContextValue::Strings(required),
- )]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn missing_subcommand(
- cmd: &Command,
- parent: String,
- available: Vec<String>,
- usage: Option<StyledStr>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::MissingSubcommand).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err.extend_context_unchecked([
- (ContextKind::InvalidSubcommand, ContextValue::String(parent)),
- (
- ContextKind::ValidSubcommand,
- ContextValue::Strings(available),
- ),
- ]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn invalid_utf8(cmd: &Command, usage: Option<StyledStr>) -> Self {
- let mut err = Self::new(ErrorKind::InvalidUtf8).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn too_many_values(
- cmd: &Command,
- val: String,
- arg: String,
- usage: Option<StyledStr>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::TooManyValues).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err.extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::InvalidValue, ContextValue::String(val)),
- ]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn too_few_values(
- cmd: &Command,
- arg: String,
- min_vals: usize,
- curr_vals: usize,
- usage: Option<StyledStr>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::TooFewValues).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err.extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (
- ContextKind::MinValues,
- ContextValue::Number(min_vals as isize),
- ),
- (
- ContextKind::ActualNumValues,
- ContextValue::Number(curr_vals as isize),
- ),
- ]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn value_validation(
- arg: String,
- val: String,
- err: Box<dyn error::Error + Send + Sync>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::ValueValidation).set_source(err);
-
- #[cfg(feature = "error-context")]
- {
- err = err.extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (ContextKind::InvalidValue, ContextValue::String(val)),
- ]);
- }
-
- err
- }
-
- pub(crate) fn wrong_number_of_values(
- cmd: &Command,
- arg: String,
- num_vals: usize,
- curr_vals: usize,
- usage: Option<StyledStr>,
- ) -> Self {
- let mut err = Self::new(ErrorKind::WrongNumberOfValues).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- err = err.extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (
- ContextKind::ExpectedNumValues,
- ContextValue::Number(num_vals as isize),
- ),
- (
- ContextKind::ActualNumValues,
- ContextValue::Number(curr_vals as isize),
- ),
- ]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- pub(crate) fn unknown_argument(
- cmd: &Command,
- arg: String,
- did_you_mean: Option<(String, Option<String>)>,
- suggested_trailing_arg: bool,
- usage: Option<StyledStr>,
- ) -> Self {
- use std::fmt::Write as _;
- let styles = cmd.get_styles();
- let invalid = &styles.get_invalid();
- let valid = &styles.get_valid();
- let mut err = Self::new(ErrorKind::UnknownArgument).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- let mut suggestions = vec![];
- if suggested_trailing_arg {
- let mut styled_suggestion = StyledStr::new();
- let _ = write!(
- styled_suggestion,
- "to pass '{}{arg}{}' as a value, use '{}-- {arg}{}'",
- invalid.render(),
- invalid.render_reset(),
- valid.render(),
- valid.render_reset()
- );
- suggestions.push(styled_suggestion);
- }
-
- err = err
- .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- match did_you_mean {
- Some((flag, Some(sub))) => {
- let mut styled_suggestion = StyledStr::new();
- let _ = write!(
- styled_suggestion,
- "'{}{sub} {flag}{}' exists",
- valid.render(),
- valid.render_reset()
- );
- suggestions.push(styled_suggestion);
- }
- Some((flag, None)) => {
- err = err.insert_context_unchecked(
- ContextKind::SuggestedArg,
- ContextValue::String(flag),
- );
- }
- None => {}
- }
- if !suggestions.is_empty() {
- err = err.insert_context_unchecked(
- ContextKind::Suggested,
- ContextValue::StyledStrs(suggestions),
- );
- }
- }
-
- err
- }
-
- pub(crate) fn unnecessary_double_dash(
- cmd: &Command,
- arg: String,
- usage: Option<StyledStr>,
- ) -> Self {
- use std::fmt::Write as _;
- let styles = cmd.get_styles();
- let invalid = &styles.get_invalid();
- let valid = &styles.get_valid();
- let mut err = Self::new(ErrorKind::UnknownArgument).with_cmd(cmd);
-
- #[cfg(feature = "error-context")]
- {
- let mut styled_suggestion = StyledStr::new();
- let _ = write!(
- styled_suggestion,
- "subcommand '{}{arg}{}' exists; to use it, remove the '{}--{}' before it",
- valid.render(),
- valid.render_reset(),
- invalid.render(),
- invalid.render_reset()
- );
-
- err = err.extend_context_unchecked([
- (ContextKind::InvalidArg, ContextValue::String(arg)),
- (
- ContextKind::Suggested,
- ContextValue::StyledStrs(vec![styled_suggestion]),
- ),
- ]);
- if let Some(usage) = usage {
- err = err
- .insert_context_unchecked(ContextKind::Usage, ContextValue::StyledStr(usage));
- }
- }
-
- err
- }
-
- fn formatted(&self) -> Cow<'_, StyledStr> {
- if let Some(message) = self.inner.message.as_ref() {
- message.formatted(&self.inner.styles)
- } else {
- let styled = F::format_error(self);
- Cow::Owned(styled)
- }
- }
-}
-
-impl<F: ErrorFormatter> From<io::Error> for Error<F> {
- fn from(e: io::Error) -> Self {
- Error::raw(ErrorKind::Io, e)
- }
-}
-
-impl<F: ErrorFormatter> From<fmt::Error> for Error<F> {
- fn from(e: fmt::Error) -> Self {
- Error::raw(ErrorKind::Format, e)
- }
-}
-
-impl<F: ErrorFormatter> std::fmt::Debug for Error<F> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
- self.inner.fmt(f)
- }
-}
-
-impl<F: ErrorFormatter> error::Error for Error<F> {
- #[allow(trivial_casts)]
- fn source(&self) -> Option<&(dyn error::Error + 'static)> {
- self.inner.source.as_ref().map(|e| e.as_ref() as _)
- }
-}
-
-impl<F: ErrorFormatter> Display for Error<F> {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- // Assuming `self.message` already has a trailing newline, from `try_help` or similar
- ok!(write!(f, "{}", self.formatted()));
- if let Some(backtrace) = self.inner.backtrace.as_ref() {
- ok!(writeln!(f));
- ok!(writeln!(f, "Backtrace:"));
- ok!(writeln!(f, "{backtrace}"));
- }
- Ok(())
- }
-}
-
-#[derive(Clone, Debug)]
-pub(crate) enum Message {
- Raw(String),
- Formatted(StyledStr),
-}
-
-impl Message {
- fn format(&mut self, cmd: &Command, usage: Option<StyledStr>) {
- match self {
- Message::Raw(s) => {
- let mut message = String::new();
- std::mem::swap(s, &mut message);
-
- let styled = format::format_error_message(
- &message,
- cmd.get_styles(),
- Some(cmd),
- usage.as_ref(),
- );
-
- *self = Self::Formatted(styled);
- }
- Message::Formatted(_) => {}
- }
- }
-
- fn formatted(&self, styles: &Styles) -> Cow<StyledStr> {
- match self {
- Message::Raw(s) => {
- let styled = format::format_error_message(s, styles, None, None);
-
- Cow::Owned(styled)
- }
- Message::Formatted(s) => Cow::Borrowed(s),
- }
- }
-}
-
-impl From<String> for Message {
- fn from(inner: String) -> Self {
- Self::Raw(inner)
- }
-}
-
-impl From<StyledStr> for Message {
- fn from(inner: StyledStr) -> 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(())
- }
-}
-
-#[test]
-fn check_auto_traits() {
- static_assertions::assert_impl_all!(Error: Send, Sync, Unpin);
-}