1use miette::{Diagnostic, NamedSource, SourceSpan};
61use std::sync::Arc;
62use thiserror::Error;
63
64#[derive(Error, Debug, Diagnostic, Clone)]
66pub enum MonError {
67 #[error(transparent)]
69 #[diagnostic(transparent)]
70 #[source_code]
71 Parser(Box<ParserError>),
72
73 #[error(transparent)]
75 #[diagnostic(transparent)]
76 #[source_code]
77 Resolver(Box<ResolverError>),
78}
79
80impl From<ParserError> for MonError {
81 fn from(err: ParserError) -> Self {
82 MonError::Parser(Box::new(err))
83 }
84}
85
86impl From<ResolverError> for MonError {
87 fn from(err: ResolverError) -> Self {
88 MonError::Resolver(Box::new(err))
89 }
90}
91
92#[derive(Error, Debug, Diagnostic, Clone)]
94#[error("Parser Error")]
95pub enum ParserError {
96 #[error("Unexpected token")]
98 #[diagnostic(
99 code(parser::unexpected_token),
100 help("The parser found a token it did not expect in this position.")
101 )]
102 UnexpectedToken {
103 #[source_code]
104 src: Arc<NamedSource<String>>,
105 #[label("Expected {expected}, but found this")]
106 span: SourceSpan,
107 expected: String,
108 },
109
110 #[error("Unexpected end of file")]
112 #[diagnostic(
113 code(parser::unexpected_eof),
114 help("The file ended unexpectedly. The parser expected more tokens.")
115 )]
116 UnexpectedEof {
117 #[source_code]
118 src: Arc<NamedSource<String>>,
119 #[label("File ended unexpectedly here")]
120 span: SourceSpan,
121 },
122
123 #[error("Missing expected token")]
125 #[diagnostic(
126 code(parser::missing_expected_token),
127 help("The parser expected a specific token that was not found.")
128 )]
129 MissingExpectedToken {
130 #[source_code]
131 src: Arc<NamedSource<String>>,
132 #[label("Expected {expected} here")]
133 span: SourceSpan,
134 expected: String,
135 },
136}
137#[derive(Error, Debug, Diagnostic, Clone)]
139#[error("Resolver Error")]
140pub enum ResolverError {
141 #[error("Module not found at path: {path}")]
143 #[diagnostic(
144 code(resolver::module_not_found),
145 help("Check that the path is correct and the file exists.")
146 )]
147 ModuleNotFound {
148 path: String,
149 #[source_code]
150 src: Arc<NamedSource<String>>,
151 #[label("...referenced here")]
152 span: SourceSpan,
153 },
154
155 #[error("Anchor '&{name}' not found")]
157 #[diagnostic(
158 code(resolver::anchor_not_found),
159 help("Ensure the anchor is defined with '&{name}: ...' in the correct scope.")
160 )]
161 AnchorNotFound {
162 name: String,
163 #[source_code]
164 src: Arc<NamedSource<String>>,
165 #[label("This anchor was not found")]
166 span: SourceSpan,
167 },
168
169 #[error("Cannot spread a non-object value")]
171 #[diagnostic(
172 code(resolver::spread_on_non_object),
173 help("The '...*' operator can only be used on an object anchor inside another object.")
174 )]
175 SpreadOnNonObject {
176 name: String,
177 #[source_code]
178 src: Arc<NamedSource<String>>,
179 #[label("'{name}' does not point to an object")]
180 span: SourceSpan,
181 },
182
183 #[error("Cannot spread a non-array value")]
185 #[diagnostic(
186 code(resolver::spread_on_non_array),
187 help("The '...*' operator can only be used on an array anchor inside another array.")
188 )]
189 SpreadOnNonArray {
190 name: String,
191 #[source_code]
192 src: Arc<NamedSource<String>>,
193 #[label("'{name}' does not point to an array")]
194 span: SourceSpan,
195 },
196
197 #[error("Circular dependency detected")]
199 #[diagnostic(
200 code(resolver::circular_dependency),
201 help("The following import chain forms a loop: {cycle}")
202 )]
203 CircularDependency {
204 cycle: String,
205 #[source_code]
206 src: Arc<NamedSource<String>>,
207 #[label("Importing this module creates a cycle")]
208 span: SourceSpan,
209 },
210
211 #[error(transparent)]
213 #[diagnostic(transparent)]
214 Validation(#[from] ValidationError),
215
216 #[error(transparent)]
218 #[diagnostic(transparent)]
219 WrappedParserError(Box<ParserError>),
220}
221
222impl From<ParserError> for ResolverError {
223 fn from(err: ParserError) -> Self {
224 ResolverError::WrappedParserError(Box::new(err))
225 }
226}
227
228#[derive(Error, Debug, Diagnostic, Clone)]
230#[error("Validation Error")]
231pub enum ValidationError {
232 #[error("Type mismatch for field '{field_name}'. Expected type {expected_type} but got {found_type}.")]
234 #[diagnostic(
235 code(validation::type_mismatch),
236 help(
237 "Ensure the value's type matches the expected type in the struct or enum definition."
238 )
239 )]
240 TypeMismatch {
241 field_name: String,
242 expected_type: String,
243 found_type: String,
244 #[source_code]
245 src: Arc<NamedSource<String>>,
246 #[label("Type mismatch here")]
247 span: SourceSpan,
248 },
249
250 #[error("Missing required field '{field_name}' for struct '{struct_name}'.")]
252 #[diagnostic(
253 code(validation::missing_field),
254 help("Add the missing field or make it optional in the struct definition.")
255 )]
256 MissingField {
257 field_name: String,
258 struct_name: String,
259 #[source_code]
260 src: Arc<NamedSource<String>>,
261 #[label("Field '{field_name}' is missing here")]
262 span: SourceSpan,
263 },
264
265 #[error("Found unexpected field '{field_name}' not defined in struct '{struct_name}'.")]
267 #[diagnostic(
268 code(validation::unexpected_field),
269 help("Remove the unexpected field or add it to the struct definition.")
270 )]
271 UnexpectedField {
272 field_name: String,
273 struct_name: String,
274 #[source_code]
275 src: Arc<NamedSource<String>>,
276 #[label("Unexpected field here")]
277 span: SourceSpan,
278 },
279
280 #[error("Undefined type '{type_name}'.")]
282 #[diagnostic(
283 code(validation::undefined_type),
284 help("Ensure the type is in scope or imported correctly.")
285 )]
286 UndefinedType {
287 type_name: String,
288 #[source_code]
289 src: Arc<NamedSource<String>>,
290 #[label("Undefined type used here")]
291 span: SourceSpan,
292 },
293
294 #[error("Variant '{variant_name}' is not defined in enum '{enum_name}'.")]
296 #[diagnostic(
297 code(validation::undefined_enum_variant),
298 help("Ensure the enum variant exists in the enum definition.")
299 )]
300 UndefinedEnumVariant {
301 variant_name: String,
302 enum_name: String,
303 #[source_code]
304 src: Arc<NamedSource<String>>,
305 #[label("Undefined enum variant used here")]
306 span: SourceSpan,
307 },
308
309 #[error("Complex collection type validation not yet implemented for field '{field_name}'.")]
311 #[diagnostic(
312 code(validation::unimplemented_collection_validation),
313 help("This type of collection validation is not yet supported.")
314 )]
315 UnimplementedCollectionValidation {
316 field_name: String,
317 #[source_code]
318 src: Arc<NamedSource<String>>,
319 #[label("Complex collection type here")]
320 span: SourceSpan,
321 },
322}
323
324impl From<MonError> for ResolverError {
325 fn from(err: MonError) -> Self {
326 match err {
327 MonError::Parser(p_err) => ResolverError::WrappedParserError(p_err),
328 MonError::Resolver(r_err) => *r_err,
329 }
330 }
331}