diff --git a/src/handlers/graphical.rs b/src/handlers/graphical.rs index b0ab478..765a1d2 100644 --- a/src/handlers/graphical.rs +++ b/src/handlers/graphical.rs @@ -379,8 +379,9 @@ impl GraphicalReportHandler { // numbers need! let linum_width = lines[..] .last() - .expect("get_lines should always return at least one line?") - .line_number + .map(|line| line.line_number) + // It's possible for the source to be an empty string. + .unwrap_or(0) .to_string() .len(); @@ -402,7 +403,7 @@ impl GraphicalReportHandler { contents.line() + 1, contents.column() + 1 )?; - } else if lines.len() == 1 { + } else if lines.len() <= 1 { writeln!(f, "{}", self.theme.characters.hbar.to_string().repeat(3))?; } else { writeln!(f, "[{}:{}]", contents.line() + 1, contents.column() + 1)?; diff --git a/tests/graphical.rs b/tests/graphical.rs index 594b3f4..2c486b9 100644 --- a/tests/graphical.rs +++ b/tests/graphical.rs @@ -34,6 +34,39 @@ fn fmt_report(diag: Report) -> String { out } +#[test] +fn empty_source() -> 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, + } + + let src = "".to_string(); + let err = MyBad { + src: NamedSource::new("bad_file.rs", src), + highlight: (0, 0).into(), + }; + let out = fmt_report(err.into()); + println!("Error: {}", out); + // For an empty string, the label cannot be rendered. + let expected = r#"oops::my::bad + + × oops! + ╭─[bad_file.rs:1:1] + ╰──── + help: try doing it better next time? +"# + .trim_start() + .to_string(); + assert_eq!(expected, out); + Ok(()) +} + #[test] fn single_line_with_wide_char() -> Result<(), MietteError> { #[derive(Debug, Diagnostic, Error)]