From 1b6a04ca5504955c571d1c97504fb45ea0befee4 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Mon, 8 Jan 2024 01:21:28 +0400 Subject: Initial vendor packages Signed-off-by: Valentin Popov --- vendor/miette/src/diagnostic_chain.rs | 93 +++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 vendor/miette/src/diagnostic_chain.rs (limited to 'vendor/miette/src/diagnostic_chain.rs') diff --git a/vendor/miette/src/diagnostic_chain.rs b/vendor/miette/src/diagnostic_chain.rs new file mode 100644 index 0000000..1e5e0c2 --- /dev/null +++ b/vendor/miette/src/diagnostic_chain.rs @@ -0,0 +1,93 @@ +/*! +Iterate over error `.diagnostic_source()` chains. +*/ + +use crate::protocol::Diagnostic; + +/// Iterator of a chain of cause errors. +#[derive(Clone, Default)] +#[allow(missing_debug_implementations)] +pub(crate) struct DiagnosticChain<'a> { + state: Option>, +} + +impl<'a> DiagnosticChain<'a> { + pub(crate) fn from_diagnostic(head: &'a dyn Diagnostic) -> Self { + DiagnosticChain { + state: Some(ErrorKind::Diagnostic(head)), + } + } + + pub(crate) fn from_stderror(head: &'a (dyn std::error::Error + 'static)) -> Self { + DiagnosticChain { + state: Some(ErrorKind::StdError(head)), + } + } +} + +impl<'a> Iterator for DiagnosticChain<'a> { + type Item = ErrorKind<'a>; + + fn next(&mut self) -> Option { + if let Some(err) = self.state.take() { + self.state = err.get_nested(); + Some(err) + } else { + None + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +impl ExactSizeIterator for DiagnosticChain<'_> { + fn len(&self) -> usize { + fn depth(d: Option<&ErrorKind<'_>>) -> usize { + match d { + Some(d) => 1 + depth(d.get_nested().as_ref()), + None => 0, + } + } + + depth(self.state.as_ref()) + } +} + +#[derive(Clone)] +pub(crate) enum ErrorKind<'a> { + Diagnostic(&'a dyn Diagnostic), + StdError(&'a (dyn std::error::Error + 'static)), +} + +impl<'a> ErrorKind<'a> { + fn get_nested(&self) -> Option> { + match self { + ErrorKind::Diagnostic(d) => d + .diagnostic_source() + .map(ErrorKind::Diagnostic) + .or_else(|| d.source().map(ErrorKind::StdError)), + ErrorKind::StdError(e) => e.source().map(ErrorKind::StdError), + } + } +} + +impl<'a> std::fmt::Debug for ErrorKind<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ErrorKind::Diagnostic(d) => d.fmt(f), + ErrorKind::StdError(e) => e.fmt(f), + } + } +} + +impl<'a> std::fmt::Display for ErrorKind<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ErrorKind::Diagnostic(d) => d.fmt(f), + ErrorKind::StdError(e) => e.fmt(f), + } + } +} -- cgit v1.2.3