pub struct LineMap<'a> {
src: &'a str,
starts: Vec<usize>,
}
impl<'a> LineMap<'a> {
#[must_use]
pub fn new(src: &'a str) -> Self {
let mut starts = vec![0usize];
for (i, byte) in src.bytes().enumerate() {
if byte == b'\n' {
starts.push(i + 1);
}
}
Self { src, starts }
}
fn line_index(&self, offset: usize) -> usize {
match self.starts.binary_search(&offset) {
Ok(line) => line,
Err(next) => next - 1, }
}
#[must_use]
pub fn loc1(&self, offset: usize) -> (usize, usize) {
let line = self.line_index(offset);
let col = self.src.get(self.starts[line]..offset).map_or(0, |s| s.chars().count());
(line + 1, col + 1)
}
#[must_use]
pub fn loc0(&self, offset: usize) -> (usize, usize) {
let line = self.line_index(offset);
let col = self.src.get(self.starts[line]..offset).map_or(0, |s| s.chars().count());
(line, col)
}
}