pub(crate) struct LineIndex {
starts: Vec<usize>,
source_len: usize,
}
impl LineIndex {
pub(crate) fn new(source: &str) -> Self {
let mut starts = vec![0usize];
for (offset, byte) in source.bytes().enumerate() {
if byte == b'\n' {
starts.push(offset + 1);
}
}
Self {
starts,
source_len: source.len(),
}
}
pub(crate) fn count(&self) -> usize {
self.starts.len()
}
pub(crate) fn span(&self, line: usize) -> (usize, usize) {
let start = self.starts.get(line).copied().unwrap_or(self.source_len);
let end = self
.starts
.get(line + 1)
.map_or(self.source_len, |next| next - 1);
(start, end.max(start))
}
}