perl_parser_pest/
error.rs1use thiserror::Error;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum ParseErrorKind {
8 UnexpectedToken,
9 UnexpectedEndOfInput,
10 InvalidSyntax,
11 InvalidNumber,
12 InvalidString,
13 InvalidRegex,
14 InvalidVariable,
15 MissingToken(String),
16 InvalidOperator,
17 InvalidIdentifier,
18}
19
20#[derive(Error, Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
22pub enum ParseError {
23 #[error("Failed to parse input")]
25 ParseFailed,
26
27 #[error("Failed to serialize scanner state")]
29 SerializationFailed,
30
31 #[error("Failed to deserialize scanner state")]
33 DeserializationFailed,
34
35 #[error("Invalid token: {0}")]
37 InvalidToken(String),
38
39 #[error("Unexpected end of input")]
41 UnexpectedEof,
42
43 #[error("Invalid Unicode sequence")]
45 InvalidUnicode,
46
47 #[error("Invalid UTF-8: {0}")]
49 InvalidUtf8(String),
50
51 #[error("Scanner error: {0}")]
53 ScannerError(String),
54
55 #[error("Failed to load language")]
57 LanguageLoadFailed,
58}
59
60pub type ParseResult<T> = Result<T, ParseError>;
62
63#[derive(Error, Debug, Clone, PartialEq)]
65pub enum ScannerError {
66 #[error("Invalid character: {0}")]
68 InvalidCharacter(char),
69
70 #[error("Unterminated string")]
72 UnterminatedString,
73
74 #[error("Unterminated comment")]
76 UnterminatedComment,
77
78 #[error("Invalid escape sequence: {0}")]
80 InvalidEscape(String),
81
82 #[error("Invalid Unicode sequence: {0}")]
84 InvalidUnicode(String),
85
86 #[error("Scanner state error: {0}")]
88 StateError(String),
89}
90
91#[derive(Error, Debug, Clone, PartialEq)]
93pub enum UnicodeError {
94 #[error("Invalid Unicode code point: {0}")]
96 InvalidCodePoint(u32),
97
98 #[error("Invalid UTF-8 sequence")]
100 InvalidUtf8,
101
102 #[error("Unicode normalization failed: {0}")]
104 NormalizationFailed(String),
105}
106
107impl From<ScannerError> for ParseError {
108 fn from(err: ScannerError) -> Self {
109 ParseError::ScannerError(err.to_string())
110 }
111}
112
113impl From<UnicodeError> for ParseError {
114 fn from(err: UnicodeError) -> Self {
115 ParseError::ScannerError(err.to_string())
116 }
117}
118
119impl From<std::str::Utf8Error> for ParseError {
120 fn from(err: std::str::Utf8Error) -> Self {
121 ParseError::InvalidUtf8(err.to_string())
122 }
123}
124
125impl From<std::string::FromUtf8Error> for ParseError {
126 fn from(err: std::string::FromUtf8Error) -> Self {
127 ParseError::InvalidUtf8(err.to_string())
128 }
129}
130
131impl From<std::io::Error> for ParseError {
132 fn from(err: std::io::Error) -> Self {
133 ParseError::ScannerError(format!("I/O error: {}", err))
134 }
135}
136
137impl ParseError {
138 pub fn new(kind: ParseErrorKind, position: usize, message: String) -> Self {
140 let error_msg = match kind {
141 ParseErrorKind::UnexpectedToken => {
142 format!("Unexpected token at position {}: {}", position, message)
143 }
144 ParseErrorKind::UnexpectedEndOfInput => {
145 format!("Unexpected end of input at position {}: {}", position, message)
146 }
147 ParseErrorKind::InvalidSyntax => {
148 format!("Invalid syntax at position {}: {}", position, message)
149 }
150 ParseErrorKind::InvalidNumber => {
151 format!("Invalid number at position {}: {}", position, message)
152 }
153 ParseErrorKind::InvalidString => {
154 format!("Invalid string at position {}: {}", position, message)
155 }
156 ParseErrorKind::InvalidRegex => {
157 format!("Invalid regex at position {}: {}", position, message)
158 }
159 ParseErrorKind::InvalidVariable => {
160 format!("Invalid variable at position {}: {}", position, message)
161 }
162 ParseErrorKind::MissingToken(ref token) => {
163 format!("Missing {} at position {}: {}", token, position, message)
164 }
165 ParseErrorKind::InvalidOperator => {
166 format!("Invalid operator at position {}: {}", position, message)
167 }
168 ParseErrorKind::InvalidIdentifier => {
169 format!("Invalid identifier at position {}: {}", position, message)
170 }
171 };
172 ParseError::InvalidToken(error_msg)
173 }
174
175 pub fn unterminated_string(position: (usize, usize)) -> Self {
177 ParseError::ScannerError(format!(
178 "Unterminated string literal at line {}, column {}",
179 position.0, position.1
180 ))
181 }
182
183 pub fn invalid_token(token: String, position: (usize, usize)) -> Self {
185 ParseError::InvalidToken(format!(
186 "Invalid token '{}' at line {}, column {}",
187 token, position.0, position.1
188 ))
189 }
190
191 pub fn unicode_error(_message: &str) -> Self {
193 ParseError::InvalidUnicode
194 }
195
196 pub fn scanner_error_simple(message: &str) -> Self {
198 ParseError::ScannerError(message.to_string())
199 }
200}