1use std::{error::Error, fmt::Display};
2
3use proc_macro2::Span;
4use proc_macro_error::{Diagnostic, Level};
5use thiserror::Error;
6
7use crate::{Delimiter, Token};
8
9#[derive(Debug, Error)]
11pub enum MacrosError {
12 #[error(transparent)]
13 Parse(ParseError),
14 #[error(transparent)]
15 User(Box<dyn Error + Send + Sync>),
16}
17
18impl From<Box<dyn Error + Send + Sync>> for MacrosError {
19 fn from(error: Box<dyn Error + Send + Sync>) -> Self {
20 Self::User(error)
21 }
22}
23
24impl From<ParseError> for MacrosError {
25 fn from(error: ParseError) -> Self {
26 Self::Parse(error)
27 }
28}
29
30impl MacrosError {
31 pub fn into_diagnostic(self) -> Diagnostic {
33 match self {
34 Self::Parse(error) => error.into_diagnostic(),
35 Self::User(error) => Diagnostic::new(Level::Error, error.to_string()),
36 }
37 }
38
39 pub fn unexpected_end_of_input(mut self, msg: &str) -> Self {
41 if let Self::Parse(error) = &mut self {
42 error.unexpected_end_of_input(msg);
43 };
44 self
45 }
46}
47
48#[derive(Debug, Error)]
50pub struct ParseError {
51 #[source]
52 pub error: ParseErrorKind,
53 pub span: Span,
54 pub level: Level,
55}
56
57impl ParseError {
58 pub fn new(span: Span, error: ParseErrorKind) -> Self {
60 Self {
61 error,
62 span,
63 level: Level::Error,
64 }
65 }
66
67 pub fn call_site(error: ParseErrorKind) -> Self {
69 Self {
70 error,
71 span: Span::call_site(),
72 level: Level::Error,
73 }
74 }
75
76 pub fn into_diagnostic(self) -> Diagnostic {
78 Diagnostic::spanned(self.span, self.level, self.error.to_string())
79 }
80
81 pub fn unexpected_end_of_input(&mut self, msg: &str) {
83 if let ParseErrorKind::UnexpectedEndOfInput(s) = &mut self.error {
84 s.push_str(msg);
85 }
86 }
87}
88
89impl Display for ParseError {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 self.error.fmt(f)
92 }
93}
94
95impl From<ParseError> for Diagnostic {
96 fn from(error: ParseError) -> Diagnostic {
97 error.into_diagnostic()
98 }
99}
100
101#[non_exhaustive]
103#[derive(Debug, Error)]
104pub enum ParseErrorKind {
105 #[error("Unknown literal: {0}")]
106 UnknownLiteral(String),
107 #[error("Invalid byte with value {0}")]
108 InvalidByte(u8),
109 #[error("Invalid escape character with byte value {0}")]
110 InvalidEscapeCharacter(u8),
111 #[error("The suffix of a numerical literal cannot start with the letter e")]
112 SuffixNoE,
113 #[error("Invalid digit {0} for base {1}")]
114 InvalidDigit(u8, u8),
115 #[error("A float literal cannot contain multiple decimal points")]
116 MultipleDecimalPointsInFloat,
117 #[error("A float literal cannot contain multiple exponent parts")]
118 MultipleExponentsInFloat,
119 #[error("A float literal cannot contain a sign in outside the exponent")]
120 UnexpectedSignInFloat,
121 #[error("A float literal cannot contain multiple signs in the exponent")]
122 MultipleSignsInFloat,
123 #[error("The exponent of a float literal must have at least one digit")]
124 MissingExponentDigits,
125 #[error("A unicode escape sequence must start with a {{")]
126 MissingUnicodeOpeningBrace,
127 #[error("A unicode escape sequence must end with a }}")]
128 TooManyUnicodeDigits,
129 #[error("A unicode escape sequence must have at least one digit")]
130 MissingUnicodeDigits,
131 #[error("Unexpected end of input, message: {0}")]
132 UnexpectedEndOfInput(String),
133 #[error("Expected {0:?}, but found {1:?}")]
134 Expected(Token, Token),
135 #[error("No matching choice found")]
136 NoMatchingChoice,
137 #[error("Expected a group delimited by {0}")]
138 ExpectedGroup(Delimiter),
139 #[error("Input is too long")]
140 InputTooLong,
141 #[error("Expected one or more repetitions, but found none")]
142 ExpectedRepetition,
143 #[error("Validator must have a non-validator pattern preceding it")]
144 InvalidValidatorPosition,
145 #[error("Validator failed with message: {0}")]
146 ValidatorFailed(String),
147}