1use draxl_ast::Span;
2use std::fmt;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct ParseError {
7 pub message: String,
8 pub span: Span,
9 pub line: usize,
10 pub column: usize,
11}
12
13impl fmt::Display for ParseError {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 write!(
16 f,
17 "{} at line {}, column {}",
18 self.message, self.line, self.column
19 )
20 }
21}
22
23impl std::error::Error for ParseError {}
24
25pub(crate) fn parse_error(source: &str, span: Span, message: &str) -> ParseError {
26 let (line, column) = line_col(source, span.start);
27 ParseError {
28 message: message.to_owned(),
29 span,
30 line,
31 column,
32 }
33}
34
35fn line_col(source: &str, offset: usize) -> (usize, usize) {
36 let mut line = 1;
37 let mut column = 1;
38 for (index, ch) in source.char_indices() {
39 if index >= offset {
40 break;
41 }
42 if ch == '\n' {
43 line += 1;
44 column = 1;
45 } else {
46 column += 1;
47 }
48 }
49 (line, column)
50}