use crate::lexer::{Span, TokenKind};
#[derive(Debug, Clone, PartialEq)]
pub struct ParseError {
pub message: String,
pub span: Span,
pub expected: Option<String>,
pub found: Option<TokenKind>,
}
impl ParseError {
#[must_use]
pub fn new(message: impl Into<String>, span: Span) -> Self {
Self {
message: message.into(),
span,
expected: None,
found: None,
}
}
#[must_use]
pub fn unexpected(expected: impl Into<String>, found: TokenKind, span: Span) -> Self {
let expected_str: String = expected.into();
Self {
message: format!(
"Unexpected token: expected {}, found {:?}",
expected_str, found
),
span,
expected: Some(expected_str),
found: Some(found),
}
}
#[must_use]
pub fn unexpected_eof(expected: impl Into<String>, span: Span) -> Self {
let expected_str: String = expected.into();
Self {
message: format!("Unexpected end of input: expected {}", expected_str),
span,
expected: Some(expected_str),
found: Some(TokenKind::Eof),
}
}
}
impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{} at position {}..{}",
self.message, self.span.start, self.span.end
)
}
}
impl std::error::Error for ParseError {}