diff options
Diffstat (limited to 'vendor/miette/src/eyreish/context.rs')
-rw-r--r-- | vendor/miette/src/eyreish/context.rs | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/vendor/miette/src/eyreish/context.rs b/vendor/miette/src/eyreish/context.rs new file mode 100644 index 0000000..3d9238b --- /dev/null +++ b/vendor/miette/src/eyreish/context.rs @@ -0,0 +1,217 @@ +use super::error::{ContextError, ErrorImpl}; +use super::{Report, WrapErr}; +use core::fmt::{self, Debug, Display, Write}; + +use std::error::Error as StdError; + +use crate::{Diagnostic, LabeledSpan}; + +mod ext { + use super::*; + + pub trait Diag { + #[cfg_attr(track_caller, track_caller)] + fn ext_report<D>(self, msg: D) -> Report + where + D: Display + Send + Sync + 'static; + } + + impl<E> Diag for E + where + E: Diagnostic + Send + Sync + 'static, + { + fn ext_report<D>(self, msg: D) -> Report + where + D: Display + Send + Sync + 'static, + { + Report::from_msg(msg, self) + } + } + + impl Diag for Report { + fn ext_report<D>(self, msg: D) -> Report + where + D: Display + Send + Sync + 'static, + { + self.wrap_err(msg) + } + } +} + +impl<T, E> WrapErr<T, E> for Result<T, E> +where + E: ext::Diag + Send + Sync + 'static, +{ + fn wrap_err<D>(self, msg: D) -> Result<T, Report> + where + D: Display + Send + Sync + 'static, + { + match self { + Ok(t) => Ok(t), + Err(e) => Err(e.ext_report(msg)), + } + } + + fn wrap_err_with<D, F>(self, msg: F) -> Result<T, Report> + where + D: Display + Send + Sync + 'static, + F: FnOnce() -> D, + { + match self { + Ok(t) => Ok(t), + Err(e) => Err(e.ext_report(msg())), + } + } + + fn context<D>(self, msg: D) -> Result<T, Report> + where + D: Display + Send + Sync + 'static, + { + self.wrap_err(msg) + } + + fn with_context<D, F>(self, msg: F) -> Result<T, Report> + where + D: Display + Send + Sync + 'static, + F: FnOnce() -> D, + { + self.wrap_err_with(msg) + } +} + +impl<D, E> Debug for ContextError<D, E> +where + D: Display, + E: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Error") + .field("msg", &Quoted(&self.msg)) + .field("source", &self.error) + .finish() + } +} + +impl<D, E> Display for ContextError<D, E> +where + D: Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Display::fmt(&self.msg, f) + } +} + +impl<D, E> StdError for ContextError<D, E> +where + D: Display, + E: StdError + 'static, +{ + fn source(&self) -> Option<&(dyn StdError + 'static)> { + Some(&self.error) + } +} + +impl<D> StdError for ContextError<D, Report> +where + D: Display, +{ + fn source(&self) -> Option<&(dyn StdError + 'static)> { + unsafe { Some(ErrorImpl::error(self.error.inner.by_ref())) } + } +} + +impl<D, E> Diagnostic for ContextError<D, E> +where + D: Display, + E: Diagnostic + 'static, +{ + fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { + self.error.code() + } + + fn severity(&self) -> Option<crate::Severity> { + self.error.severity() + } + + fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { + self.error.help() + } + + fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { + self.error.url() + } + + fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> { + self.error.labels() + } + + fn source_code(&self) -> Option<&dyn crate::SourceCode> { + self.error.source_code() + } + + fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> { + self.error.related() + } +} + +impl<D> Diagnostic for ContextError<D, Report> +where + D: Display, +{ + fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { + unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).code() } + } + + fn severity(&self) -> Option<crate::Severity> { + unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).severity() } + } + + fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { + unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).help() } + } + + fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { + unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).url() } + } + + fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> { + unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).labels() } + } + + fn source_code(&self) -> Option<&dyn crate::SourceCode> { + self.error.source_code() + } + + fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> { + self.error.related() + } +} + +struct Quoted<D>(D); + +impl<D> Debug for Quoted<D> +where + D: Display, +{ + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_char('"')?; + Quoted(&mut *formatter).write_fmt(format_args!("{}", self.0))?; + formatter.write_char('"')?; + Ok(()) + } +} + +impl Write for Quoted<&mut fmt::Formatter<'_>> { + fn write_str(&mut self, s: &str) -> fmt::Result { + Display::fmt(&s.escape_debug(), self.0) + } +} + +pub(crate) mod private { + use super::*; + + pub trait Sealed {} + + impl<T, E> Sealed for Result<T, E> where E: ext::Diag {} + impl<T> Sealed for Option<T> {} +} |