1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, LexerError>;
7
8#[derive(Debug, Clone, Error)]
10pub enum LexerError {
11 #[error("Unterminated string literal starting at position {position}")]
13 UnterminatedString { position: usize },
14
15 #[error("Unterminated regex starting at position {position}")]
17 UnterminatedRegex { position: usize },
18
19 #[error("Invalid escape sequence '\\{char}' at position {position}")]
21 InvalidEscape { char: char, position: usize },
22
23 #[error("Invalid numeric literal at position {position}: {reason}")]
25 InvalidNumber { position: usize, reason: String },
26
27 #[error("Unexpected character '{char}' at position {position}")]
29 UnexpectedChar { char: char, position: usize },
30
31 #[error("Invalid UTF-8 at position {position}")]
33 InvalidUtf8 { position: usize },
34
35 #[error("Heredoc error at position {position}: {reason}")]
37 HeredocError { position: usize, reason: String },
38
39 #[error("{0}")]
41 Other(String),
42}
43
44impl LexerError {
45 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}