use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Position {
pub line: usize,
pub column: usize,
pub offset: usize,
}
impl Position {
pub fn new(line: usize, column: usize, offset: usize) -> Self {
Self {
line,
column,
offset,
}
}
pub fn start() -> Self {
Self::new(1, 1, 0)
}
}
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.line, self.column)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Span {
pub start: Position,
pub end: Position,
}
impl Span {
pub fn new(start: Position, end: Position) -> Self {
Self { start, end }
}
pub fn at(pos: Position) -> Self {
Self::new(pos, pos)
}
pub fn start() -> Self {
Self::at(Position::start())
}
}
impl fmt::Display for Span {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.start == self.end {
write!(f, "{}", self.start)
} else {
write!(f, "{}-{}", self.start, self.end)
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ParseErrorKind {
UnexpectedToken {
expected: Vec<String>,
found: String,
},
UnexpectedEof {
expected: Vec<String>,
},
UnmatchedDelimiter {
opening: char,
position: Position,
},
InvalidNumber {
value: String,
reason: String,
},
InvalidLatexCommand {
command: String,
},
UnknownFunction {
name: String,
},
InvalidSubscript {
reason: String,
},
InvalidSuperscript {
reason: String,
},
MalformedMatrix {
reason: String,
},
EmptyExpression,
Custom(String),
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParseError {
pub kind: ParseErrorKind,
pub span: Option<Span>,
pub context: Option<String>,
pub suggestion: Option<String>,
}
pub type ParseResult<T> = Result<T, ParseError>;