parent
daff23dd98
commit
9d4fef5222
@ -0,0 +1,65 @@ |
||||
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 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.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) |
||||
} |
||||
} |
Loading…
Reference in new issue