feat(graphical): Inherit source code to causes (#401)

This commit is contained in:
George Pollard 2024-11-27 12:53:19 +09:00 committed by GitHub
parent 68d47fa8b5
commit 465e6b6ab6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 5 deletions

View File

@ -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)?;

View File

@ -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);
}