1use crate::span::Span;
3use miette::Diagnostic;
4use thiserror::Error;
5
6#[derive(Error, Debug, Diagnostic, Clone)]
8pub enum ParseError {
9 #[error("unexpected token: found `{found}`, expected {expected}")]
10 UnexpectedToken {
11 found: String,
12 expected: String,
13 #[label("here")]
14 span: miette::SourceSpan,
15 },
16
17 #[error("unexpected end of input, expected {expected}")]
18 UnexpectedEof {
19 expected: String,
20 #[label("here")]
21 span: miette::SourceSpan,
22 },
23
24 #[error("{message}")]
25 Custom {
26 message: String,
27 #[label("{message}")]
28 span: miette::SourceSpan,
29 },
30
31 #[error("invalid token")]
32 InvalidToken {
33 #[label("invalid token")]
34 span: miette::SourceSpan,
35 },
36}
37
38impl ParseError {
39 #[must_use]
40 pub fn unexpected_token(found: &str, expected: &str, span: Span) -> Self {
41 Self::UnexpectedToken {
42 found: found.to_string(),
43 expected: expected.to_string(),
44 span: (span.start, span.len()).into(),
45 }
46 }
47
48 #[must_use]
49 pub fn unexpected_eof(expected: &str, pos: usize) -> Self {
50 Self::UnexpectedEof {
51 expected: expected.to_string(),
52 span: (pos, 0).into(),
53 }
54 }
55
56 #[must_use]
57 pub fn custom(message: &str, span: Span) -> Self {
58 Self::Custom {
59 message: message.to_string(),
60 span: (span.start, span.len()).into(),
61 }
62 }
63}
64
65pub type ParseResult<T> = Result<T, ParseError>;