use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use crate::coords::Coords;
use crate::lexer::Token;
use crate::parser::Parser;
pub type ParserResult<T> = Result<T, Error>;
#[derive(Debug, Copy, Clone)]
pub enum Stage {
Lexer,
Parser,
}
impl Display for Stage {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Stage::Lexer => write!(f, "lexing"),
Stage::Parser => write!(f, "parsing"),
}
}
}
#[derive(Debug, Clone)]
pub enum Details {
EndOfInput,
StreamFailure,
NonUtf8InputDetected,
UnexpectedToken(Token),
PairExpected,
InvalidObject,
InvalidArray,
InvalidCharacter(char),
MatchFailed(String, String),
InvalidNumericRepresentation(String),
InvalidEscapeSequence(String),
InvalidUnicodeEscapeSequence(String),
}
impl Display for Details {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Details::EndOfInput => write!(f, "end of input reached"),
Details::StreamFailure => write!(f, "failure in the underlying stream"),
Details::NonUtf8InputDetected => write!(f, "non-UTF8 input"),
Details::UnexpectedToken(token) => write!(f, "unexpected token found: {}", token),
Details::PairExpected => write!(f, "pair expected, something else was found"),
Details::InvalidObject => write!(f, "invalid object"),
Details::InvalidArray => write!(f, "invalid array"),
Details::InvalidCharacter(ch) => write!(f, "invalid character: \'{}\'", ch),
Details::MatchFailed(first, second) => write!(
f,
"a match failed. Looking for \"{}\", found \"{}\"",
first, second
),
Details::InvalidNumericRepresentation(repr) => {
write!(f, "invalid number representation: \"{}\"", repr)
}
Details::InvalidEscapeSequence(seq) => {
write!(f, "invalid escape sequence: \"{}\"", seq)
}
Details::InvalidUnicodeEscapeSequence(seq) => {
write!(f, "invalid unicode escape sequence: \"{}\"", seq)
}
}
}
}
#[derive(Debug, Clone)]
pub struct Error {
pub stage: Stage,
pub details: Details,
pub coords: Coords,
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Stage: {}, Details: {}, Coords: {}",
self.stage, self.details, self.coords
)
}
}
#[macro_export]
macro_rules! lexer_error {
($details: expr, $coords : expr) => {
Err(Error {
stage: Stage::Lexer,
details: $details,
coords: $coords,
})
};
}
#[macro_export]
macro_rules! parser_error {
($details: expr, $coords: expr) => {
Err(Error {
stage: Stage::Parser,
details: $details,
coords: $coords,
})
};
}