Skip to content

Commit

Permalink
feat(graphical): Inherit source code to causes (#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
Porges authored Nov 27, 2024
1 parent 68d47fa commit 465e6b6
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
26 changes: 21 additions & 5 deletions src/handlers/graphical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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)?;
Expand Down
50 changes: 50 additions & 0 deletions tests/test_diagnostic_source_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 465e6b6

Please sign in to comment.