mago_type_syntax/
error.rs

1use serde::Serialize;
2
3use mago_span::HasPosition;
4use mago_span::HasSpan;
5use mago_span::Position;
6use mago_span::Span;
7
8use crate::token::TypeTokenKind;
9
10#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize)]
11pub enum SyntaxError {
12    UnexpectedToken(u8, Position),
13    UnrecognizedToken(u8, Position),
14    UnexpectedEndOfFile(Position),
15}
16
17#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
18pub enum ParseError {
19    SyntaxError(SyntaxError),
20    UnexpectedEndOfFile(Vec<TypeTokenKind>, Position),
21    UnexpectedToken(Vec<TypeTokenKind>, TypeTokenKind, Span),
22    UnclosedLiteralString(Span),
23}
24
25impl From<SyntaxError> for ParseError {
26    fn from(error: SyntaxError) -> Self {
27        ParseError::SyntaxError(error)
28    }
29}
30
31impl HasPosition for SyntaxError {
32    fn position(&self) -> Position {
33        match self {
34            SyntaxError::UnexpectedToken(_, position) => *position,
35            SyntaxError::UnrecognizedToken(_, position) => *position,
36            SyntaxError::UnexpectedEndOfFile(position) => *position,
37        }
38    }
39}
40
41impl HasSpan for ParseError {
42    fn span(&self) -> Span {
43        match self {
44            ParseError::SyntaxError(error) => {
45                let position = error.position();
46
47                Span::new(position, position)
48            }
49            ParseError::UnexpectedEndOfFile(_, position) => Span::new(*position, *position),
50            ParseError::UnexpectedToken(_, _, span) => *span,
51            ParseError::UnclosedLiteralString(span) => *span,
52        }
53    }
54}
55
56impl std::fmt::Display for SyntaxError {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        match self {
59            SyntaxError::UnexpectedToken(token, position) => {
60                write!(f, "Unexpected token {token} at {position}")
61            }
62            SyntaxError::UnrecognizedToken(token, position) => {
63                write!(f, "Unrecognized token {token} at {position}")
64            }
65            SyntaxError::UnexpectedEndOfFile(position) => {
66                write!(f, "Unexpected end of file at {position}")
67            }
68        }
69    }
70}
71
72impl std::error::Error for SyntaxError {
73    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
74        None
75    }
76}
77
78impl std::fmt::Display for ParseError {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        match self {
81            ParseError::SyntaxError(err) => write!(f, "{err}"),
82            ParseError::UnexpectedEndOfFile(_, position) => {
83                write!(f, "Unexpected end of file at {position}")
84            }
85            ParseError::UnexpectedToken(_, token, span) => {
86                write!(f, "Unexpected token {token:?} at {span}")
87            }
88            ParseError::UnclosedLiteralString(span) => {
89                write!(f, "Unclosed literal string at {span}")
90            }
91        }
92    }
93}
94
95impl std::error::Error for ParseError {
96    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
97        match self {
98            ParseError::SyntaxError(err) => Some(err),
99            _ => None,
100        }
101    }
102}