use super::Location;
pub(super) struct LineIndex {
newlines: Vec<usize>,
}
impl LineIndex {
pub(super) fn new(content: &str) -> Self {
Self {
newlines: content
.bytes()
.enumerate()
.filter_map(|(idx, byte)| (byte == b'\n').then_some(idx))
.collect(),
}
}
pub(super) fn location(&self, offset: usize) -> Location {
let previous_newlines = self
.newlines
.partition_point(|newline_offset| *newline_offset < offset);
let line_start = if previous_newlines == 0 {
0
} else {
self.newlines[previous_newlines - 1] + 1
};
Location {
line: previous_newlines + 1,
column: offset - line_start + 1,
position: offset,
}
}
}