Skip to content

Commit

Permalink
feat(handlers): propagate source code to related errors
Browse files Browse the repository at this point in the history
Fixes #99
  • Loading branch information
tailhook authored and zkat committed Feb 20, 2022
1 parent 5051926 commit 3a17fce
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 10 deletions.
14 changes: 9 additions & 5 deletions src/handlers/graphical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,10 @@ impl GraphicalReportHandler {
self.render_header(f, diagnostic)?;
writeln!(f)?;
self.render_causes(f, diagnostic)?;
self.render_snippets(f, diagnostic)?;
let src = diagnostic.source_code();
self.render_snippets(f, diagnostic, src)?;
self.render_footer(f, diagnostic)?;
self.render_related(f, diagnostic)?;
self.render_related(f, diagnostic, src)?;
if let Some(footer) = &self.footer {
writeln!(f)?;
let width = self.termwidth.saturating_sub(4);
Expand Down Expand Up @@ -226,6 +227,7 @@ impl GraphicalReportHandler {
&self,
f: &mut impl fmt::Write,
diagnostic: &(dyn Diagnostic),
parent_src: Option<&dyn SourceCode>,
) -> fmt::Result {
if let Some(related) = diagnostic.related() {
writeln!(f)?;
Expand All @@ -234,9 +236,10 @@ impl GraphicalReportHandler {
self.render_header(f, rel)?;
writeln!(f)?;
self.render_causes(f, rel)?;
self.render_snippets(f, rel)?;
let src = rel.source_code().or(parent_src);
self.render_snippets(f, rel, src)?;
self.render_footer(f, rel)?;
self.render_related(f, rel)?;
self.render_related(f, rel, src)?;
}
}
Ok(())
Expand All @@ -246,8 +249,9 @@ impl GraphicalReportHandler {
&self,
f: &mut impl fmt::Write,
diagnostic: &(dyn Diagnostic),
opt_source: Option<&dyn SourceCode>,
) -> fmt::Result {
if let Some(source) = diagnostic.source_code() {
if let Some(source) = opt_source {
if let Some(labels) = diagnostic.labels() {
let mut labels = labels.collect::<Vec<_>>();
labels.sort_unstable_by_key(|l| l.inner().offset());
Expand Down
14 changes: 9 additions & 5 deletions src/handlers/narratable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ impl NarratableReportHandler {
) -> fmt::Result {
self.render_header(f, diagnostic)?;
self.render_causes(f, diagnostic)?;
self.render_snippets(f, diagnostic)?;
let src = diagnostic.source_code();
self.render_snippets(f, diagnostic, src)?;
self.render_footer(f, diagnostic)?;
self.render_related(f, diagnostic)?;
self.render_related(f, diagnostic, src)?;
if let Some(footer) = &self.footer {
writeln!(f, "{}", footer)?;
}
Expand Down Expand Up @@ -105,6 +106,7 @@ impl NarratableReportHandler {
&self,
f: &mut impl fmt::Write,
diagnostic: &(dyn Diagnostic),
parent_src: Option<&dyn SourceCode>,
) -> fmt::Result {
if let Some(related) = diagnostic.related() {
writeln!(f)?;
Expand All @@ -113,9 +115,10 @@ impl NarratableReportHandler {
self.render_header(f, rel)?;
writeln!(f)?;
self.render_causes(f, rel)?;
self.render_snippets(f, rel)?;
let src = rel.source_code().or(parent_src);
self.render_snippets(f, rel, src)?;
self.render_footer(f, rel)?;
self.render_related(f, rel)?;
self.render_related(f, rel, src)?;
}
}
Ok(())
Expand All @@ -125,8 +128,9 @@ impl NarratableReportHandler {
&self,
f: &mut impl fmt::Write,
diagnostic: &(dyn Diagnostic),
source_code: Option<&dyn SourceCode>,
) -> fmt::Result {
if let Some(source) = diagnostic.source_code() {
if let Some(source) = source_code {
if let Some(labels) = diagnostic.labels() {
let mut labels = labels.collect::<Vec<_>>();
labels.sort_unstable_by_key(|l| l.inner().offset());
Expand Down
60 changes: 60 additions & 0 deletions tests/graphical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,3 +820,63 @@ Error: oops::my::bad
assert_eq!(expected, out);
Ok(())
}

#[test]
fn related_source_code_propagation() -> Result<(), MietteError> {
#[derive(Debug, Diagnostic, Error)]
#[error("oops!")]
#[diagnostic(code(oops::my::bad), help("try doing it better next time?"))]
struct MyBad {
#[source_code]
src: NamedSource,
#[label("this bit here")]
highlight: SourceSpan,
#[related]
related: Vec<InnerError>,
}

#[derive(Debug, Diagnostic, Error)]
#[error("oops!")]
#[diagnostic(code(oops::my::bad))]
struct InnerError {
#[label("this bit here")]
highlight: SourceSpan,
}

let src = "source\n text\n here".to_string();
let err = MyBad {
src: NamedSource::new("bad_file.rs", src.clone()),
highlight: (9, 4).into(),
related: vec![InnerError {
highlight: (0, 6).into(),
}],
};
let out = fmt_report(err.into());
println!("Error: {}", out);
let expected = r#"oops::my::bad
× oops!
╭─[bad_file.rs:1:1]
1 │ source
2 │ text
· ──┬─
· ╰── this bit here
3 │ here
╰────
help: try doing it better next time?
Error: oops::my::bad
× oops!
╭─[bad_file.rs:1:1]
1 │ source
· ───┬──
· ╰── this bit here
2 │ text
╰────
"#
.trim_start()
.to_string();
assert_eq!(expected, out);
Ok(())
}
59 changes: 59 additions & 0 deletions tests/narrated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,3 +605,62 @@ diagnostic code: oops::my::bad
assert_eq!(expected, out);
Ok(())
}

#[test]
fn related_source_code_propagation() -> Result<(), MietteError> {
#[derive(Debug, Diagnostic, Error)]
#[error("oops!")]
#[diagnostic(code(oops::my::bad), help("try doing it better next time?"))]
struct MyBad {
#[source_code]
src: NamedSource,
#[label("this bit here")]
highlight: SourceSpan,
#[related]
related: Vec<InnerError>,
}

#[derive(Debug, Diagnostic, Error)]
#[error("oops!")]
#[diagnostic(code(oops::my::bad))]
struct InnerError {
#[label("this bit here")]
highlight: SourceSpan,
}

let src = "source\n text\n here".to_string();
let err = MyBad {
src: NamedSource::new("bad_file.rs", src.clone()),
highlight: (9, 4).into(),
related: vec![InnerError {
highlight: (0, 6).into(),
}],
};
let out = fmt_report(err.into());
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
snippet line 2: text
label at line 2, columns 3 to 6: this bit here
snippet line 3: here
diagnostic help: try doing it better next time?
diagnostic code: oops::my::bad
Error: oops!
Diagnostic severity: error
Begin snippet for bad_file.rs starting at line 1, column 1
snippet line 1: source
label at line 1, columns 1 to 6: this bit here
snippet line 2: text
diagnostic code: oops::my::bad
"#
.trim_start()
.to_string();
assert_eq!(expected, out);
Ok(())
}

0 comments on commit 3a17fce

Please sign in to comment.