diff --git a/src/error/context.rs b/src/error/context.rs new file mode 100644 index 00000000000..3356cd1bb13 --- /dev/null +++ b/src/error/context.rs @@ -0,0 +1,17 @@ +/// Semantics for a piece of error information +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum ContextKind { + /// An opaque message to the user + Custom, +} + +/// A piece of error information +#[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum ContextValue { + /// [`ContextKind`] is self-sufficient, no additional information needed + None, + /// A single value + Value(String), +} diff --git a/src/error/mod.rs b/src/error/mod.rs index 6349661ab87..97805487d9b 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -19,8 +19,11 @@ use crate::{ App, AppSettings, }; +mod context; mod kind; +pub use context::ContextKind; +pub use context::ContextValue; pub use kind::ErrorKind; /// Short hand for [`Result`] type @@ -45,9 +48,8 @@ pub struct Error { #[derive(Debug)] struct ErrorInner { - /// The type of error kind: ErrorKind, - /// Formatted error message, enhancing the cause message with extra information + context: Vec<(ContextKind, ContextValue)>, message: Message, source: Option>, wait_on_exit: bool, @@ -82,6 +84,11 @@ impl Error { self.inner.kind } + /// Additional information to further qualify the error + pub fn context(&self) -> impl Iterator { + 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 { @@ -147,6 +154,7 @@ impl Error { Self { inner: Box::new(ErrorInner { kind, + context: Vec::new(), message: message.into(), source: None, wait_on_exit,