From 465e6b6ab627f8da34baa5f46441d944fb88186e Mon Sep 17 00:00:00 2001 From: George Pollard Date: Wed, 27 Nov 2024 12:53:19 +0900 Subject: [PATCH] feat(graphical): Inherit source code to causes (#401) --- src/handlers/graphical.rs | 26 +++++++++++--- tests/test_diagnostic_source_macro.rs | 50 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/handlers/graphical.rs b/src/handlers/graphical.rs index 8c4a9a5..9e0948c 100644 --- a/src/handlers/graphical.rs +++ b/src/handlers/graphical.rs @@ -218,9 +218,18 @@ impl GraphicalReportHandler { f: &mut impl fmt::Write, diagnostic: &(dyn Diagnostic), ) -> fmt::Result { + self.render_report_inner(f, diagnostic, diagnostic.source_code()) + } + + fn render_report_inner( + &self, + f: &mut impl fmt::Write, + diagnostic: &(dyn Diagnostic), + parent_src: Option<&dyn SourceCode>, + ) -> fmt::Result { + let src = diagnostic.source_code().or(parent_src); self.render_header(f, diagnostic)?; - self.render_causes(f, diagnostic)?; - let src = diagnostic.source_code(); + self.render_causes(f, diagnostic, src)?; self.render_snippets(f, diagnostic, src)?; self.render_footer(f, diagnostic)?; self.render_related(f, diagnostic, src)?; @@ -278,7 +287,14 @@ impl GraphicalReportHandler { Ok(()) } - fn render_causes(&self, f: &mut impl fmt::Write, diagnostic: &(dyn Diagnostic)) -> fmt::Result { + fn render_causes( + &self, + f: &mut impl fmt::Write, + diagnostic: &(dyn Diagnostic), + parent_src: Option<&dyn SourceCode>, + ) -> fmt::Result { + let src = diagnostic.source_code().or(parent_src); + let (severity_style, severity_icon) = match diagnostic.severity() { Some(Severity::Error) | None => (self.theme.styles.error, &self.theme.characters.error), Some(Severity::Warning) => (self.theme.styles.warning, &self.theme.characters.warning), @@ -356,7 +372,7 @@ impl GraphicalReportHandler { inner_renderer.with_cause_chain = false; // Since everything from here on is indented, shrink the virtual terminal inner_renderer.termwidth -= rest_indent.width(); - inner_renderer.render_report(&mut inner, diag)?; + inner_renderer.render_report_inner(&mut inner, diag, src)?; // If there was no header, remove the leading newline let inner = inner.trim_start_matches('\n'); @@ -410,8 +426,8 @@ impl GraphicalReportHandler { Some(Severity::Advice) => write!(f, "Advice: ")?, }; inner_renderer.render_header(f, rel)?; - inner_renderer.render_causes(f, rel)?; let src = rel.source_code().or(parent_src); + inner_renderer.render_causes(f, rel, src)?; inner_renderer.render_snippets(f, rel, src)?; inner_renderer.render_footer(f, rel)?; inner_renderer.render_related(f, rel, src)?; diff --git a/tests/test_diagnostic_source_macro.rs b/tests/test_diagnostic_source_macro.rs index bbc2179..b21e091 100644 --- a/tests/test_diagnostic_source_macro.rs +++ b/tests/test_diagnostic_source_macro.rs @@ -299,3 +299,53 @@ fn test_nested_cause_chains_for_related_errors_are_output() { assert_eq!(expected, out); } + +#[cfg(feature = "fancy-no-backtrace")] +#[derive(Debug, miette::Diagnostic, thiserror::Error)] +#[error("A case1 error happened")] +enum NestedEnumError { + Case1 { + #[source_code] + code: String, + #[diagnostic_source] + the_other_err: Case1Inner, + }, +} + +#[derive(Debug, miette::Diagnostic, thiserror::Error)] +#[error("I am the inner error")] +struct Case1Inner { + #[label("inner-label")] + label: (usize, usize), +} + +#[cfg(feature = "fancy-no-backtrace")] +#[test] +fn source_is_inherited_to_causes() { + let diag = NestedEnumError::Case1 { + code: String::from("this is the parent source"), + the_other_err: Case1Inner { label: (8, 3) }, + }; + let mut out = String::new(); + miette::GraphicalReportHandler::new_themed(miette::GraphicalTheme::unicode_nocolor()) + .with_width(80) + .with_footer("Yooo, a footer".to_string()) + .render_report(&mut out, &diag) + .unwrap(); + println!("{}", out); + + let expected = r#" + × A case1 error happened + ╰─▶ × I am the inner error + ╭──── + 1 │ this is the parent source + · ─┬─ + · ╰── inner-label + ╰──── + + + Yooo, a footer +"#; + + assert_eq!(expected, out); +}