Skip to main content

oxide_sql_core/parser/
error.rs

1//! Parser error types.
2
3use crate::lexer::{Span, TokenKind};
4
5/// A parse error.
6#[derive(Debug, Clone, PartialEq)]
7pub struct ParseError {
8    /// The error message.
9    pub message: String,
10    /// The location of the error.
11    pub span: Span,
12    /// Expected tokens (if applicable).
13    pub expected: Option<String>,
14    /// The actual token found.
15    pub found: Option<TokenKind>,
16}
17
18impl ParseError {
19    /// Creates a new parse error.
20    #[must_use]
21    pub fn new(message: impl Into<String>, span: Span) -> Self {
22        Self {
23            message: message.into(),
24            span,
25            expected: None,
26            found: None,
27        }
28    }
29
30    /// Creates an "unexpected token" error.
31    #[must_use]
32    pub fn unexpected(expected: impl Into<String>, found: TokenKind, span: Span) -> Self {
33        let expected_str: String = expected.into();
34        Self {
35            message: format!(
36                "Unexpected token: expected {}, found {:?}",
37                expected_str, found
38            ),
39            span,
40            expected: Some(expected_str),
41            found: Some(found),
42        }
43    }
44
45    /// Creates an "unexpected end of input" error.
46    #[must_use]
47    pub fn unexpected_eof(expected: impl Into<String>, span: Span) -> Self {
48        let expected_str: String = expected.into();
49        Self {
50            message: format!("Unexpected end of input: expected {}", expected_str),
51            span,
52            expected: Some(expected_str),
53            found: Some(TokenKind::Eof),
54        }
55    }
56}
57
58impl std::fmt::Display for ParseError {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        write!(
61            f,
62            "{} at position {}..{}",
63            self.message, self.span.start, self.span.end
64        )
65    }
66}
67
68impl std::error::Error for ParseError {}