use miette::{LabeledSpan, MietteHandler, ReportHandler, Severity, SourceCode}; use nu_protocol::engine::StateWorkingSet; use thiserror::Error; /// This error exists so that we can defer SourceCode handling. It simply /// forwards most methods, except for `.source_code()`, which we provide. #[derive(Error)] #[error("{0}")] pub struct CliError<'src>( pub &'src (dyn miette::Diagnostic + Send + Sync + 'static), pub &'src StateWorkingSet<'src>, ); impl std::fmt::Debug for CliError<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { MietteHandler::default().debug(self, f)?; Ok(()) } } impl<'src> miette::Diagnostic for CliError<'src> { fn code<'a>(&'a self) -> Option> { self.0.code() } fn severity(&self) -> Option { self.0.severity() } fn help<'a>(&'a self) -> Option> { self.0.help() } fn url<'a>(&'a self) -> Option> { self.0.url() } fn labels<'a>(&'a self) -> Option + 'a>> { self.0.labels() } // Finally, we redirect the source_code method to our own source. fn source_code(&self) -> Option<&dyn SourceCode> { if let Some(source_code) = self.0.source_code() { Some(source_code) } else { Some(&self.1) } } fn related<'a>(&'a self) -> Option + 'a>> { self.0.related() } }