Skip to main content

perl_lexer/
error.rs

1//! Error types for the Perl lexer
2
3use thiserror::Error;
4
5/// Result type for lexer operations
6pub type Result<T> = std::result::Result<T, LexerError>;
7
8/// Errors that can occur during lexing
9#[derive(Debug, Clone, Error)]
10pub enum LexerError {
11    /// Unterminated string literal
12    #[error("Unterminated string literal starting at position {position}")]
13    UnterminatedString { position: usize },
14
15    /// Unterminated regex
16    #[error("Unterminated regex starting at position {position}")]
17    UnterminatedRegex { position: usize },
18
19    /// Invalid escape sequence
20    #[error("Invalid escape sequence '\\{char}' at position {position}")]
21    InvalidEscape { char: char, position: usize },
22
23    /// Invalid numeric literal
24    #[error("Invalid numeric literal at position {position}: {reason}")]
25    InvalidNumber { position: usize, reason: String },
26
27    /// Unexpected character
28    #[error("Unexpected character '{char}' at position {position}")]
29    UnexpectedChar { char: char, position: usize },
30
31    /// Invalid UTF-8
32    #[error("Invalid UTF-8 at position {position}")]
33    InvalidUtf8 { position: usize },
34
35    /// Heredoc error
36    #[error("Heredoc error at position {position}: {reason}")]
37    HeredocError { position: usize, reason: String },
38
39    /// Generic error
40    #[error("{0}")]
41    Other(String),
42}
43
44impl LexerError {
45    /// Get the position where the error occurred
46    pub fn position(&self) -> Option<usize> {
47        match self {
48            LexerError::UnterminatedString { position }
49            | LexerError::UnterminatedRegex { position }
50            | LexerError::InvalidEscape { position, .. }
51            | LexerError::InvalidNumber { position, .. }
52            | LexerError::UnexpectedChar { position, .. }
53            | LexerError::InvalidUtf8 { position }
54            | LexerError::HeredocError { position, .. } => Some(*position),
55            LexerError::Other(_) => None,
56        }
57    }
58}