prost_reflect/dynamic/text_format/parse/
error.rs1use logos::Span;
2use std::{
3 error::Error,
4 fmt::{self, Display},
5};
6
7#[derive(Debug)]
9#[cfg_attr(docsrs, doc(cfg(feature = "text-format")))]
10pub struct ParseError {
11 kind: Box<ParseErrorKind>,
12 #[cfg(feature = "miette")]
13 source: String,
14}
15
16impl ParseError {
17 #[cfg(feature = "miette")]
18 pub(crate) fn new(kind: ParseErrorKind, source: &str) -> Self {
19 ParseError {
20 kind: Box::new(kind),
21 source: source.to_owned(),
22 }
23 }
24
25 #[cfg(not(feature = "miette"))]
26 pub(crate) fn new(kind: ParseErrorKind, _: &str) -> Self {
27 ParseError {
28 kind: Box::new(kind),
29 }
30 }
31}
32
33#[derive(Debug, Clone, PartialEq)]
34#[cfg_attr(feature = "miette", derive(miette::Diagnostic))]
35pub(crate) enum ParseErrorKind {
36 InvalidToken {
37 #[cfg_attr(feature = "miette", label("found here"))]
38 span: Span,
39 },
40 InvalidStringCharacters {
41 #[cfg_attr(feature = "miette", label("invalid characters"))]
42 span: Span,
43 },
44 InvalidStringEscape {
45 #[cfg_attr(feature = "miette", label("defined here"))]
46 span: Span,
47 },
48 InvalidUtf8String {
49 #[cfg_attr(feature = "miette", label("defined here"))]
50 span: Span,
51 },
52 NoSpaceBetweenIntAndIdent {
53 #[cfg_attr(feature = "miette", label("found here"))]
54 span: Span,
55 },
56 UnexpectedToken {
57 expected: String,
58 found: String,
59 #[cfg_attr(feature = "miette", label("found here"))]
60 span: Span,
61 },
62 UnexpectedEof {
63 expected: String,
64 },
65 #[cfg_attr(
66 feature = "miette",
67 diagnostic(help("the value must be between {min} and {max} inclusive"))
68 )]
69 IntegerValueOutOfRange {
70 expected: String,
71 actual: String,
72 min: String,
73 max: String,
74 #[cfg_attr(feature = "miette", label("defined here"))]
75 span: Span,
76 },
77 FieldNotFound {
78 field_name: String,
79 message_name: String,
80 #[cfg_attr(feature = "miette", label("set here"))]
81 span: Span,
82 },
83 FieldAlreadySet {
84 field_name: String,
85 #[cfg_attr(feature = "miette", label("set here"))]
86 span: Span,
87 },
88 OneofAlreadySet {
89 oneof_name: String,
90 #[cfg_attr(feature = "miette", label("set here"))]
91 span: Span,
92 },
93 ExtensionNotFound {
94 extension_name: String,
95 message_name: String,
96 #[cfg_attr(feature = "miette", label("set here"))]
97 span: Span,
98 },
99 MessageNotFound {
100 message_name: String,
101 #[cfg_attr(feature = "miette", label("used here"))]
102 span: Span,
103 },
104 EnumValueNotFound {
105 value_name: String,
106 enum_name: String,
107 #[cfg_attr(feature = "miette", label("used here"))]
108 span: Span,
109 },
110 InvalidTypeForAny {
111 #[cfg_attr(feature = "miette", label("used here"))]
112 span: Span,
113 },
114 InvalidMapKey,
115}
116
117impl Display for ParseErrorKind {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 match self {
120 ParseErrorKind::InvalidToken { .. } => write!(f, "invalid token"),
121 ParseErrorKind::InvalidStringCharacters { .. } => write!(f, "invalid string character"),
122 ParseErrorKind::InvalidStringEscape { .. } => write!(f, "invalid string escape"),
123 ParseErrorKind::InvalidUtf8String { .. } => write!(f, "string is not valid utf-8"),
124 ParseErrorKind::NoSpaceBetweenIntAndIdent { .. } => write!(
125 f,
126 "whitespace is required between an integer literal and an identifier"
127 ),
128 ParseErrorKind::UnexpectedToken {
129 expected, found, ..
130 } => write!(f, "expected {}, but found '{}'", expected, found),
131 ParseErrorKind::UnexpectedEof { expected, .. } => {
132 write!(f, "expected {}, but reached end of input", expected)
133 }
134 ParseErrorKind::IntegerValueOutOfRange {
135 expected, actual, ..
136 } => write!(
137 f,
138 "expected value to be {}, but the value {} is out of range",
139 expected, actual
140 ),
141 ParseErrorKind::FieldNotFound {
142 field_name,
143 message_name,
144 ..
145 } => write!(
146 f,
147 "field '{}' not found for message '{}'",
148 field_name, message_name
149 ),
150 ParseErrorKind::FieldAlreadySet { field_name, .. } => {
151 write!(f, "'{}' is already set", field_name,)
152 }
153 ParseErrorKind::OneofAlreadySet { oneof_name, .. } => {
154 write!(f, "a value is already set for oneof '{}'", oneof_name)
155 }
156 ParseErrorKind::ExtensionNotFound {
157 extension_name,
158 message_name,
159 ..
160 } => {
161 write!(
162 f,
163 "extension '{}' not found for message '{}'",
164 extension_name, message_name
165 )
166 }
167 ParseErrorKind::MessageNotFound { message_name, .. } => {
168 write!(f, "message type '{}' not found", message_name)
169 }
170 ParseErrorKind::EnumValueNotFound {
171 value_name,
172 enum_name,
173 ..
174 } => {
175 write!(
176 f,
177 "value '{}' was not found for enum '{}'",
178 value_name, enum_name
179 )
180 }
181 ParseErrorKind::InvalidTypeForAny { .. } => write!(
182 f,
183 "the field type must be 'google.protobuf.Any' to use Any expansion syntax"
184 ),
185 ParseErrorKind::InvalidMapKey { .. } => write!(f, "invalid value type for map key"),
186 }
187 }
188}
189
190impl Error for ParseErrorKind {}
191
192impl Display for ParseError {
193 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194 self.kind.fmt(f)
195 }
196}
197
198impl Error for ParseError {}
199
200#[cfg(feature = "miette")]
201#[cfg_attr(docsrs, doc(cfg(feature = "miette")))]
202impl miette::Diagnostic for ParseError {
203 fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
204 self.kind.code()
205 }
206
207 fn severity(&self) -> Option<miette::Severity> {
208 self.kind.severity()
209 }
210
211 fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
212 self.kind.help()
213 }
214
215 fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
216 self.kind.url()
217 }
218
219 fn source_code(&self) -> Option<&dyn miette::SourceCode> {
220 Some(&self.source)
221 }
222
223 fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {
224 self.kind.labels()
225 }
226
227 fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn miette::Diagnostic> + 'a>> {
228 self.kind.related()
229 }
230
231 fn diagnostic_source(&self) -> Option<&dyn miette::Diagnostic> {
232 self.kind.diagnostic_source()
233 }
234}