use std::fmt::Display;
use super::Location;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Error {
pub etype: ErrorType,
pub loc: Location,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ErrorType {
UnexpectedEof {
expected: Option<&'static str>,
},
InvalidChar {
char: char,
expected: Option<&'static str>,
},
InvalidPlaceholder {
details: &'static str,
},
UnterminatedString,
EmptyIdent,
UnterminatedIdent,
}
impl std::error::Error for Error {}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.etype {
ErrorType::UnexpectedEof { expected } => {
write!(f, "Unexpected end-of-file")?;
if let Some(expected) = expected {
write!(f, ", expected {expected}")?;
}
}
ErrorType::InvalidChar { char, expected } => {
write!(f, "Invalid character '{}'", char.escape_debug())?;
if let Some(expected) = expected {
write!(f, ", expected {expected}")?;
}
}
ErrorType::InvalidPlaceholder { details } => {
write!(f, "Invalid placeholder; {details}")?;
}
ErrorType::UnterminatedString => {
write!(f, "Unterminated string literal")?;
}
ErrorType::EmptyIdent => {
write!(f, "Empty identifier")?;
}
ErrorType::UnterminatedIdent => {
write!(f, "Unterminated identifier")?;
}
}
write!(f, " {}", self.loc)
}
}