use draxl_ast::Span;
use draxl_parser::ParseError;
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PatchTextError {
pub message: String,
pub span: Span,
pub line: usize,
pub column: usize,
}
impl fmt::Display for PatchTextError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{} at line {}, column {}",
self.message, self.line, self.column
)
}
}
impl std::error::Error for PatchTextError {}
pub(crate) fn patch_text_error(source: &str, span: Span, message: &str) -> PatchTextError {
let (line, column) = line_col(source, span.start);
PatchTextError {
message: message.to_owned(),
span,
line,
column,
}
}
pub(crate) fn map_fragment_parse_error(
source: &str,
fragment_start: usize,
error: ParseError,
) -> PatchTextError {
let span = Span {
start: fragment_start + error.span.start,
end: fragment_start + error.span.end,
};
patch_text_error(source, span, &error.message)
}
fn line_col(source: &str, offset: usize) -> (usize, usize) {
let mut line = 1;
let mut column = 1;
for (index, ch) in source.char_indices() {
if index >= offset {
break;
}
if ch == '\n' {
line += 1;
column = 1;
} else {
column += 1;
}
}
(line, column)
}