1use chisel_common::char::coords::Coords;
2use chisel_lexers::json::lexer::LexerError;
3use std::fmt::{Display, Formatter};
4
5pub mod json;
7
8pub type ParserResult<T> = Result<T, ParserError>;
10
11#[derive(Debug, Clone, PartialEq)]
13pub enum ParserErrorDetails {
14 InvalidFile,
16 ZeroLengthInput,
18 EndOfInput,
20 StreamFailure,
23 NonUtf8InputDetected,
25 UnexpectedToken(String),
28 ValueExpected,
30 PairExpected,
32 InvalidRootObject,
34 InvalidObject,
36 InvalidArray,
38 InvalidCharacter(char),
40 MatchFailed(String, String),
42 InvalidNumericRepresentation(String),
44 InvalidEscapeSequence(String),
46 InvalidUnicodeEscapeSequence(String),
48 LexerError(String),
50}
51
52impl Display for ParserErrorDetails {
53 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54 match self {
55 ParserErrorDetails::InvalidFile => write!(f, "invalid file specified"),
56 ParserErrorDetails::ZeroLengthInput => write!(f, "zero length input"),
57 ParserErrorDetails::EndOfInput => write!(f, "end of input reached"),
58 ParserErrorDetails::StreamFailure => write!(f, "failure in the underlying stream"),
59 ParserErrorDetails::NonUtf8InputDetected => write!(f, "non-UTF8 input"),
60 ParserErrorDetails::UnexpectedToken(token) => {
61 write!(f, "unexpected token found: {}", token)
62 }
63 ParserErrorDetails::ValueExpected => {
64 write!(f, "value expected, but a comma was found")
65 }
66 ParserErrorDetails::PairExpected => {
67 write!(f, "pair expected, something else was found")
68 }
69 ParserErrorDetails::InvalidRootObject => write!(f, "invalid JSON"),
70 ParserErrorDetails::InvalidObject => write!(f, "invalid object"),
71 ParserErrorDetails::InvalidArray => write!(f, "invalid array"),
72 ParserErrorDetails::InvalidCharacter(ch) => write!(f, "invalid character: \'{}\'", ch),
73 ParserErrorDetails::MatchFailed(first, second) => write!(
74 f,
75 "a match failed. Looking for \"{}\", found \"{}\"",
76 first, second
77 ),
78 ParserErrorDetails::InvalidNumericRepresentation(repr) => {
79 write!(f, "invalid number representation: \"{}\"", repr)
80 }
81 ParserErrorDetails::InvalidEscapeSequence(seq) => {
82 write!(f, "invalid escape sequence: \"{}\"", seq)
83 }
84 ParserErrorDetails::InvalidUnicodeEscapeSequence(seq) => {
85 write!(f, "invalid unicode escape sequence: \"{}\"", seq)
86 }
87 ParserErrorDetails::LexerError(repr) => {
88 write!(f, "lexer error reported: \"{}\"", repr)
89 }
90 }
91 }
92}
93
94#[derive(Debug, Clone)]
96pub struct ParserError {
97 pub details: ParserErrorDetails,
99 pub coords: Option<Coords>,
101}
102
103impl Display for ParserError {
104 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
105 if self.coords.is_some() {
106 write!(
107 f,
108 "details: {}, coords: {}",
109 self.details,
110 self.coords.unwrap()
111 )
112 } else {
113 write!(f, "details: {}", self.details)
114 }
115 }
116}
117
118impl From<LexerError> for ParserError {
120 fn from(value: LexerError) -> Self {
121 ParserError {
122 details: ParserErrorDetails::LexerError(value.details.to_string()),
123 coords: value.coords,
124 }
125 }
126}
127
128#[macro_export]
130macro_rules! parser_error {
131 ($details: expr, $coords: expr) => {
132 Err(ParserError {
133 details: $details,
134 coords: Some($coords),
135 })
136 };
137 ($details: expr) => {
138 Err(ParserError {
139 details: $details,
140 coords: None,
141 })
142 };
143}