1use miette::{Diagnostic, NamedSource, SourceSpan};
2use std::sync::Arc;
3use thiserror::Error;
4
5#[derive(Error, Debug, Diagnostic, Clone)]
6pub enum MonError {
7 #[error(transparent)]
8 #[diagnostic(transparent)]
9 #[source_code]
10 Parser(Box<ParserError>),
11
12 #[error(transparent)]
13 #[diagnostic(transparent)]
14 #[source_code]
15 Resolver(Box<ResolverError>),
16}
17
18impl From<ParserError> for MonError {
19 fn from(err: ParserError) -> Self {
20 MonError::Parser(Box::new(err))
21 }
22}
23
24impl From<ResolverError> for MonError {
25 fn from(err: ResolverError) -> Self {
26 MonError::Resolver(Box::new(err))
27 }
28}
29
30#[derive(Error, Debug, Diagnostic, Clone)]
31#[error("Parser Error")]
32pub enum ParserError {
33 #[error("Unexpected token")]
34 #[diagnostic(
35 code(parser::unexpected_token),
36 help("The parser found a token it did not expect in this position.")
37 )]
38 UnexpectedToken {
39 #[source_code]
40 src: Arc<NamedSource<String>>,
41 #[label("Expected {expected}, but found this")]
42 span: SourceSpan,
43 expected: String,
44 },
45
46 #[error("Unexpected end of file")]
47 #[diagnostic(
48 code(parser::unexpected_eof),
49 help("The file ended unexpectedly. The parser expected more tokens.")
50 )]
51 UnexpectedEof {
52 #[source_code]
53 src: Arc<NamedSource<String>>,
54 #[label("File ended unexpectedly here")]
55 span: SourceSpan,
56 },
57
58 #[error("Missing expected token")]
59 #[diagnostic(
60 code(parser::missing_expected_token),
61 help("The parser expected a specific token that was not found.")
62 )]
63 MissingExpectedToken {
64 #[source_code]
65 src: Arc<NamedSource<String>>,
66 #[label("Expected {expected} here")]
67 span: SourceSpan,
68 expected: String,
69 },
70}
71#[derive(Error, Debug, Diagnostic, Clone)]
72#[error("Resolver Error")]
73pub enum ResolverError {
74 #[error("Module not found at path: {path}")]
75 #[diagnostic(
76 code(resolver::module_not_found),
77 help("Check that the path is correct and the file exists.")
78 )]
79 ModuleNotFound {
80 path: String,
81 #[source_code]
82 src: Arc<NamedSource<String>>,
83 #[label("...referenced here")]
84 span: SourceSpan,
85 },
86
87 #[error("Anchor '&{name}' not found")]
88 #[diagnostic(
89 code(resolver::anchor_not_found),
90 help("Ensure the anchor is defined with '&{name}: ...' in the correct scope.")
91 )]
92 AnchorNotFound {
93 name: String,
94 #[source_code]
95 src: Arc<NamedSource<String>>,
96 #[label("This anchor was not found")]
97 span: SourceSpan,
98 },
99
100 #[error("Cannot spread a non-object value")]
101 #[diagnostic(
102 code(resolver::spread_on_non_object),
103 help("The '...*' operator can only be used on an object anchor inside another object.")
104 )]
105 SpreadOnNonObject {
106 name: String,
107 #[source_code]
108 src: Arc<NamedSource<String>>,
109 #[label("'{name}' does not point to an object")]
110 span: SourceSpan,
111 },
112
113 #[error("Cannot spread a non-array value")]
114 #[diagnostic(
115 code(resolver::spread_on_non_array),
116 help("The '...*' operator can only be used on an array anchor inside another array.")
117 )]
118 SpreadOnNonArray {
119 name: String,
120 #[source_code]
121 src: Arc<NamedSource<String>>,
122 #[label("'{name}' does not point to an array")]
123 span: SourceSpan,
124 },
125
126 #[error("Circular dependency detected")]
127 #[diagnostic(
128 code(resolver::circular_dependency),
129 help("The following import chain forms a loop: {cycle}")
130 )]
131 CircularDependency {
132 cycle: String,
133 #[source_code]
134 src: Arc<NamedSource<String>>,
135 #[label("Importing this module creates a cycle")]
136 span: SourceSpan,
137 },
138
139 #[error(transparent)]
140 #[diagnostic(transparent)]
141 Validation(#[from] ValidationError),
142
143 #[error(transparent)]
144 #[diagnostic(transparent)]
145 WrappedParserError(Box<ParserError>),
146}
147
148impl From<ParserError> for ResolverError {
149 fn from(err: ParserError) -> Self {
150 ResolverError::WrappedParserError(Box::new(err))
151 }
152}
153
154#[derive(Error, Debug, Diagnostic, Clone)]
155#[error("Validation Error")]
156pub enum ValidationError {
157 #[error("Type mismatch for field '{field_name}'. Expected type {expected_type} but got {found_type}.")]
158 #[diagnostic(
159 code(validation::type_mismatch),
160 help(
161 "Ensure the value's type matches the expected type in the struct or enum definition."
162 )
163 )]
164 TypeMismatch {
165 field_name: String,
166 expected_type: String,
167 found_type: String,
168 #[source_code]
169 src: Arc<NamedSource<String>>,
170 #[label("Type mismatch here")]
171 span: SourceSpan,
172 },
173
174 #[error("Missing required field '{field_name}' for struct '{struct_name}'.")]
175 #[diagnostic(
176 code(validation::missing_field),
177 help("Add the missing field or make it optional in the struct definition.")
178 )]
179 MissingField {
180 field_name: String,
181 struct_name: String,
182 #[source_code]
183 src: Arc<NamedSource<String>>,
184 #[label("Field '{field_name}' is missing here")]
185 span: SourceSpan,
186 },
187
188 #[error("Found unexpected field '{field_name}' not defined in struct '{struct_name}'.")]
189 #[diagnostic(
190 code(validation::unexpected_field),
191 help("Remove the unexpected field or add it to the struct definition.")
192 )]
193 UnexpectedField {
194 field_name: String,
195 struct_name: String,
196 #[source_code]
197 src: Arc<NamedSource<String>>,
198 #[label("Unexpected field here")]
199 span: SourceSpan,
200 },
201
202 #[error("Undefined type '{type_name}'.")]
203 #[diagnostic(
204 code(validation::undefined_type),
205 help("Ensure the type is defined or imported correctly.")
206 )]
207 UndefinedType {
208 type_name: String,
209 #[source_code]
210 src: Arc<NamedSource<String>>,
211 #[label("Undefined type used here")]
212 span: SourceSpan,
213 },
214
215 #[error("Variant '{variant_name}' is not defined in enum '{enum_name}'.")]
216 #[diagnostic(
217 code(validation::undefined_enum_variant),
218 help("Ensure the enum variant exists in the enum definition.")
219 )]
220 UndefinedEnumVariant {
221 variant_name: String,
222 enum_name: String,
223 #[source_code]
224 src: Arc<NamedSource<String>>,
225 #[label("Undefined enum variant used here")]
226 span: SourceSpan,
227 },
228
229 #[error("Complex collection type validation not yet implemented for field '{field_name}'.")]
230 #[diagnostic(
231 code(validation::unimplemented_collection_validation),
232 help("This type of collection validation is not yet supported.")
233 )]
234 UnimplementedCollectionValidation {
235 field_name: String,
236 #[source_code]
237 src: Arc<NamedSource<String>>,
238 #[label("Complex collection type here")]
239 span: SourceSpan,
240 },
241}
242
243impl From<MonError> for ResolverError {
244 fn from(err: MonError) -> Self {
245 match err {
246 MonError::Parser(p_err) => ResolverError::WrappedParserError(p_err),
247 MonError::Resolver(r_err) => *r_err,
248 }
249 }
250}