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