From 2b5699180c3565de7eb0f662bf24c65728436e5c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 27 May 2021 13:22:12 -0500 Subject: [PATCH] fix: Count lines correctly I didn't count on how `buffer.lines().count()` would handle different corner cases, like slices with no `\n`, slices with trailing `\n`, etc. Fixes #259 --- CHANGELOG.md | 4 ++++ src/file.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 074efec..d878e0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate +#### Bug Fixes + +- Line numbers were off by `1 + ` + ## [1.0.0] - 2021-05-25 ## [0.4.0] - 2021-05-21 diff --git a/src/file.rs b/src/file.rs index 94582e0..306f11c 100644 --- a/src/file.rs +++ b/src/file.rs @@ -502,7 +502,7 @@ impl AccumulateLineNum { fn line_num(&mut self, buffer: &[u8], byte_offset: usize) -> usize { assert!(self.last_offset <= byte_offset); let slice = &buffer[self.last_offset..byte_offset]; - let newlines = slice.lines().count(); + let newlines = slice.find_iter(b"\n").count(); let line_num = self.line_num + newlines; self.line_num = line_num; self.last_offset = byte_offset; @@ -675,6 +675,31 @@ mod test { assert_eq!(actual, "foo happy world"); } + #[test] + fn test_line_count_first() { + let mut accum_line_num = AccumulateLineNum::new(); + let line_num = accum_line_num.line_num(b"hello world", 6); + assert_eq!(line_num, 1); + } + + #[test] + fn test_line_count_second() { + let mut accum_line_num = AccumulateLineNum::new(); + let line_num = accum_line_num.line_num(b"1\n2\n3", 2); + assert_eq!(line_num, 2); + } + + #[test] + fn test_line_count_multiple() { + let mut accum_line_num = AccumulateLineNum::new(); + let line_num = accum_line_num.line_num(b"1\n2\n3", 0); + assert_eq!(line_num, 1); + let line_num = accum_line_num.line_num(b"1\n2\n3", 2); + assert_eq!(line_num, 2); + let line_num = accum_line_num.line_num(b"1\n2\n3", 4); + assert_eq!(line_num, 3); + } + #[test] fn test_extract_line_single_line() { let (line, offset) = extract_line(b"hello world", 6);