use std::fmt;
#[derive(Debug)]
pub struct CodeRegion {
index: usize,
line: usize,
col: usize,
}
impl CodeRegion {
pub(crate) fn from_context_index(context: &str, index: usize) -> Self {
let mut region = CodeRegion {
index,
line: 1,
col: 0,
};
let mut prev_char = '\0';
for (cur_index, c) in context.chars().enumerate() {
if cur_index <= index {
let mut need_move_col = true;
if c == '\r' {
region.set_new_line();
need_move_col = false;
} else if c == '\n' {
if prev_char == '\r' {
} else {
region.set_new_line();
}
need_move_col = false;
}
if need_move_col {
region.move_one();
}
prev_char = c;
}
}
region
}
pub fn set_new_line(&mut self) {
self.line += 1;
self.col = 0;
}
pub fn move_one(&mut self) {
self.col += 1;
}
}
impl fmt::Display for CodeRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let output = format!("[line:{},col:{},index:{}]", self.line, self.col, self.index);
f.write_str(output.as_str())
}
}