oxide-sql-core 0.2.0

Type-safe SQL parser and builder with compile-time validation
Documentation
//! Parser error types.

use crate::lexer::{Span, TokenKind};

/// A parse error.
#[derive(Debug, Clone, PartialEq)]
pub struct ParseError {
    /// The error message.
    pub message: String,
    /// The location of the error.
    pub span: Span,
    /// Expected tokens (if applicable).
    pub expected: Option<String>,
    /// The actual token found.
    pub found: Option<TokenKind>,
}

impl ParseError {
    /// Creates a new parse error.
    #[must_use]
    pub fn new(message: impl Into<String>, span: Span) -> Self {
        Self {
            message: message.into(),
            span,
            expected: None,
            found: None,
        }
    }

    /// Creates an "unexpected token" error.
    #[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),
        }
    }

    /// Creates an "unexpected end of input" error.
    #[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 {}