|
|
|
use std::{fmt, cmp};
|
|
|
|
use std::fmt::{Formatter, Debug};
|
|
|
|
|
|
|
|
/// Position in the input string
|
|
|
|
#[derive(PartialEq, Clone, Default)]
|
|
|
|
pub struct SourcePosition {
|
|
|
|
/// The line number on which the error occurred.
|
|
|
|
pub line: u32,
|
|
|
|
/// The column number on which the error occurred.
|
|
|
|
pub column: u32,
|
|
|
|
/// The index in the given string which caused the error.
|
|
|
|
pub index: u32,
|
|
|
|
/// File index if there are multiple files
|
|
|
|
pub file: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for SourcePosition {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
|
|
write!(f, "{}:{}", self.line, self.column)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SourcePosition {
|
|
|
|
pub fn with_file(mut self, file: u32) -> Self {
|
|
|
|
self.file = file;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Debug for SourcePosition {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
if f.alternate() {
|
|
|
|
f.debug_struct("SourcePosition")
|
|
|
|
.field("line", &self.line)
|
|
|
|
.field("column", &self.column)
|
|
|
|
.field("index", &self.index)
|
|
|
|
.field("file", &self.file)
|
|
|
|
.finish()
|
|
|
|
} else {
|
|
|
|
// shorter version
|
|
|
|
write!(f, "Pos({}|{}:{})", self.file, self.line, self.column)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn get_line_and_column(s: &str, pos: usize) -> SourcePosition {
|
|
|
|
let mut line: usize = 1;
|
|
|
|
let mut col: isize = -1;
|
|
|
|
for c in s.chars().take(pos + 1) {
|
|
|
|
if c == '\n' {
|
|
|
|
line += 1;
|
|
|
|
col = -1;
|
|
|
|
} else {
|
|
|
|
col += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SourcePosition {
|
|
|
|
line: line as u32,
|
|
|
|
column: cmp::max(col, 0) as u32,
|
|
|
|
index: pos as u32,
|
|
|
|
file: 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Build a span
|
|
|
|
pub(crate) fn spos(s: &str, pos: usize) -> SourcePosition {
|
|
|
|
if pos >= s.len() {
|
|
|
|
Default::default()
|
|
|
|
} else {
|
|
|
|
get_line_and_column(s, pos)
|
|
|
|
}
|
|
|
|
}
|