diff --git a/Cargo.toml b/Cargo.toml index ac5b006..89219be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ indenter = "0.3.0" rustversion = "1.0" trybuild = { version = "1.0.19", features = ["diff"] } syn = { version = "1.0", features = ["full"] } +pretty_assertions = "1.2.1" [features] default = [] diff --git a/src/handlers/graphical.rs b/src/handlers/graphical.rs index 21aed36..18a2000 100644 --- a/src/handlers/graphical.rs +++ b/src/handlers/graphical.rs @@ -272,20 +272,47 @@ impl GraphicalReportHandler { parent_src: Option<&dyn SourceCode>, ) -> fmt::Result { if let Some(related) = diagnostic.related() { - writeln!(f)?; - for rel in related { + let related: Vec<_> = related.collect(); + writeln!( + f, + "{}{}There were {} related diagnostics:", + if related.is_empty() { + self.theme.characters.lcross + } else { + self.theme.characters.ltop + }, + self.theme.characters.hbar, + related.len() + )?; + let width = self.termwidth.saturating_sub(2); + let mut inner = String::new(); + for (idx, rel) in related.into_iter().enumerate() { + let init_ident = format!( + "{}{} {}.", + self.theme.characters.lcross, + self.theme.characters.hbar, + idx + 1 + ); + let subseq_ident = format!("{} ", self.theme.characters.vbar); + let opts = textwrap::Options::new(width) + .initial_indent(&init_ident) + .subsequent_indent(&subseq_ident); match diagnostic.severity() { - Some(Severity::Error) | None => write!(f, "Error: ")?, - Some(Severity::Warning) => write!(f, "Warning: ")?, - Some(Severity::Advice) => write!(f, "Advice: ")?, + Some(Severity::Error) | None => write!(&mut inner, "Error: ")?, + Some(Severity::Warning) => write!(&mut inner, "Warning: ")?, + Some(Severity::Advice) => write!(&mut inner, "Advice: ")?, }; - self.render_header(f, rel)?; - writeln!(f)?; - self.render_causes(f, rel)?; + self.render_header(&mut inner, rel)?; + writeln!(&mut inner)?; + self.render_causes(&mut inner, 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, src)?; + self.render_snippets(&mut inner, rel, src)?; + self.render_footer(&mut inner, rel)?; + self.render_related(&mut inner, rel, src)?; + + writeln!(f, "{}", textwrap::fill(&inner, opts))?; + + inner.clear(); } } Ok(()) diff --git a/tests/graphical.rs b/tests/graphical.rs index 35d6ccf..f4529b7 100644 --- a/tests/graphical.rs +++ b/tests/graphical.rs @@ -5,6 +5,7 @@ use miette::{ NarratableReportHandler, Report, SourceSpan, }; use thiserror::Error; +use pretty_assertions::assert_eq; fn fmt_report(diag: Report) -> String { let mut out = String::new(); @@ -784,11 +785,22 @@ fn related() -> Result<(), MietteError> { let err = MyBad { src: NamedSource::new("bad_file.rs", src.clone()), highlight: (9, 4).into(), - related: vec![MyBad { - src: NamedSource::new("bad_file.rs", src), - highlight: (0, 6).into(), - related: vec![], - }], + related: vec![ + MyBad { + src: NamedSource::new("bad_file.rs", src.clone()), + highlight: (0, 6).into(), + related: vec![MyBad { + src: NamedSource::new("bad_file.rs", src.clone()), + highlight: (0, 6).into(), + related: vec![], + }], + }, + MyBad { + src: NamedSource::new("bad_file.rs", src.clone()), + highlight: (0, 6).into(), + related: vec![], + }, + ], }; let out = fmt_report(err.into()); println!("Error: {}", out); @@ -803,19 +815,46 @@ fn related() -> Result<(), MietteError> { 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 - ╰──── - help: try doing it better next time? - +╭─There were 2 related diagnostics: +├─ 1.Error: oops::my::bad +│ +│ +│ × oops! +│ ╭─[bad_file.rs:1:1] +│ 1 │ source +│ · ───┬── +│ · ╰── this bit here +│ 2 │ text +│ ╰──── +│ help: try doing it better next time? +│ ╭─There were 1 related diagnostics: +│ ├─ 1.Error: oops::my::bad +│ │ +│ │ +│ │ × oops! +│ │ ╭─[bad_file.rs:1:1] +│ │ 1 │ source +│ │ · ───┬── +│ │ · ╰── this bit here +│ │ 2 │ text +│ │ ╰──── +│ │ help: try doing it better next time? +│ │ ├─There were 0 related diagnostics: +│ │ +│ +├─ 2.Error: oops::my::bad +│ +│ +│ × oops! +│ ╭─[bad_file.rs:1:1] +│ 1 │ source +│ · ───┬── +│ · ╰── this bit here +│ 2 │ text +│ ╰──── +│ help: try doing it better next time? +│ ├─There were 0 related diagnostics: +│ "# .trim_start() .to_string(); @@ -866,17 +905,18 @@ fn related_source_code_propagation() -> Result<(), MietteError> { 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 - ╰──── +╭─There were 1 related diagnostics: +├─ 1.Error: oops::my::bad +│ +│ +│ × oops! +│ ╭─[bad_file.rs:1:1] +│ 1 │ source +│ · ───┬── +│ · ╰── this bit here +│ 2 │ text +│ ╰──── +│ "# .trim_start() .to_string();