sentience_tokenize/
span.rs1use crate::Span;
2
3pub struct LineMap {
4 starts: Vec<usize>,
5}
6
7impl LineMap {
8 pub fn new(src: &str) -> Self {
9 let mut starts = Vec::with_capacity(128);
10 starts.push(0);
11 for (i, b) in src.bytes().enumerate() {
12 if b == b'\n' {
13 starts.push(i + 1);
14 }
15 }
16 Self { starts }
17 }
18
19 pub fn to_line_col(&self, byte: usize) -> (usize, usize) {
20 let i = match self.starts.binary_search(&byte) {
21 Ok(k) => k,
22 Err(k) => k.saturating_sub(1),
23 };
24 (i + 1, byte.saturating_sub(self.starts[i]) + 1)
25 }
26
27 pub fn span_lines(&self, span: Span) -> ((usize, usize), (usize, usize)) {
28 (self.to_line_col(span.start), self.to_line_col(span.end))
29 }
30
31 pub fn line_count(&self) -> usize {
32 self.starts.len()
33 }
34}