From 1493701a40c9e0223c2c10f7b5b554b9aa800dba Mon Sep 17 00:00:00 2001 From: R4 Cheng Date: Wed, 21 Aug 2024 20:46:57 +0800 Subject: [PATCH 1/4] test: Add a test case for issue 57 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running tests/formatter.rs (target/debug/deps/formatter-d39ddd6093209828) running 40 tests ... failures: ---- test_line_number_0 stdout ---- thread 'test_line_number_0' panicked at tests/formatter.rs:928:5: ---- expected: tests/formatter.rs:919:20 ++++ actual: In-memory 1 1 | error: dummy 2 - --> file/path:0:3 3 - | 4 - 0 | foo 5 - | ^ 6 - |∅ 2 + --> file/path:0:3 3 + | 4 + 0 |foo 5 + | ^ 6 + |∅ failures: test_line_number_0 test result: FAILED. 39 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s --- tests/formatter.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/formatter.rs b/tests/formatter.rs index 7f914de..40e5f40 100644 --- a/tests/formatter.rs +++ b/tests/formatter.rs @@ -905,3 +905,25 @@ error: unused optional dependency let renderer = Renderer::plain(); assert_data_eq!(renderer.render(input).to_string(), expected); } + +// for issue 57 +#[test] +fn test_line_number_0() { + let input = Level::Error.title("dummy").snippet( + Snippet::source("foo") + .origin("file/path") + .line_start(0) + .annotation(Level::Error.span(2..3)), // bar\nbaz + ); + + let expected = str![[r#" +error: dummy + --> file/path:0:3 + | +0 | foo + | ^ + | +"#]]; + let renderer = Renderer::plain(); + assert_data_eq!(renderer.render(input).to_string(), expected); +} From 7ffe4b23d7890494468897d5d3773b352cd79bdb Mon Sep 17 00:00:00 2001 From: R4 Cheng Date: Fri, 23 Aug 2024 11:31:41 +0800 Subject: [PATCH 2/4] fix: Add None case for finding max line number - Line number width is 1 if max line number is 0 - Line number witdh is 0 if max line number is None - Update test_line_number_0 in tests/formatter.rs to reflect new behavior - Fix issue #57 Running tests/formatter.rs (target/debug/deps/formatter-d39ddd6093209828) running 40 tests ... test result: ok. 40 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s --- src/renderer/display_list.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/renderer/display_list.rs b/src/renderer/display_list.rs index eea4971..4b3abf1 100644 --- a/src/renderer/display_list.rs +++ b/src/renderer/display_list.rs @@ -72,18 +72,17 @@ impl<'a> fmt::Debug for DisplayList<'a> { impl<'a> Display for DisplayList<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let lineno_width = self.body.iter().fold(0, |max, set| { + let lineno_width = self.body.iter().fold(None, |max, set| { set.display_lines.iter().fold(max, |max, line| match line { - DisplayLine::Source { lineno, .. } => cmp::max(lineno.unwrap_or(0), max), + DisplayLine::Source { lineno, .. } => std::cmp::max(max, *lineno), _ => max, }) }); - let lineno_width = if lineno_width == 0 { - lineno_width - } else if self.anonymized_line_numbers { - ANONYMIZED_LINE_NUM.len() - } else { - ((lineno_width as f64).log10().floor() as usize) + 1 + let lineno_width = match lineno_width { + None => 0, + Some(_max) if self.anonymized_line_numbers => ANONYMIZED_LINE_NUM.len(), + Some(0) => 1, + Some(max) => (max as f64).log10().floor() as usize + 1, }; let multiline_depth = self.body.iter().fold(0, |max, set| { From 9a89193e536d0562f0bea53f2f1f68b9e8c4e6ca Mon Sep 17 00:00:00 2001 From: R4 Cheng Date: Wed, 21 Aug 2024 21:10:23 +0800 Subject: [PATCH 3/4] refactor: Rename variable The fold chaining is to find max line number rather than line number width --- src/renderer/display_list.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/display_list.rs b/src/renderer/display_list.rs index 4b3abf1..516adc5 100644 --- a/src/renderer/display_list.rs +++ b/src/renderer/display_list.rs @@ -72,13 +72,13 @@ impl<'a> fmt::Debug for DisplayList<'a> { impl<'a> Display for DisplayList<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let lineno_width = self.body.iter().fold(None, |max, set| { + let max_lineno = self.body.iter().fold(None, |max, set| { set.display_lines.iter().fold(max, |max, line| match line { DisplayLine::Source { lineno, .. } => std::cmp::max(max, *lineno), _ => max, }) }); - let lineno_width = match lineno_width { + let lineno_width = match max_lineno { None => 0, Some(_max) if self.anonymized_line_numbers => ANONYMIZED_LINE_NUM.len(), Some(0) => 1, From 7863752dad6b3bd495f3cf5916527994753d1da9 Mon Sep 17 00:00:00 2001 From: R4 Cheng Date: Mon, 26 Aug 2024 13:29:31 +0800 Subject: [PATCH 4/4] refactor: Extract get_max_lineno free function --- src/renderer/display_list.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/renderer/display_list.rs b/src/renderer/display_list.rs index 516adc5..6a1cbd9 100644 --- a/src/renderer/display_list.rs +++ b/src/renderer/display_list.rs @@ -72,12 +72,7 @@ impl<'a> fmt::Debug for DisplayList<'a> { impl<'a> Display for DisplayList<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let max_lineno = self.body.iter().fold(None, |max, set| { - set.display_lines.iter().fold(max, |max, line| match line { - DisplayLine::Source { lineno, .. } => std::cmp::max(max, *lineno), - _ => max, - }) - }); + let max_lineno = get_max_lineno(&self.body); let lineno_width = match max_lineno { None => 0, Some(_max) if self.anonymized_line_numbers => ANONYMIZED_LINE_NUM.len(), @@ -149,6 +144,16 @@ impl<'a> DisplayList<'a> { } } +fn get_max_lineno(body: &[DisplaySet<'_>]) -> Option { + let max_lineno = body.iter().fold(None, |max, set| { + set.display_lines.iter().fold(max, |max, line| match line { + DisplayLine::Source { lineno, .. } => cmp::max(max, *lineno), + _ => max, + }) + }); + max_lineno +} + #[derive(Debug, PartialEq)] pub(crate) struct DisplaySet<'a> { pub(crate) display_lines: Vec>,