1use duck_diagnostic::{Diagnostic, DiagnosticCode, Severity};
16use serde::{Deserialize, Serialize};
17
18pub mod metadata;
19
20pub type DiagResult<T = ()> = Result<T, Diagnostic<Code>>;
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
49pub enum Code {
50 #[cfg(feature = "lexer")]
53 InvalidCharacter,
54 #[cfg(feature = "lexer")]
56 InvalidFrontMatter,
57 #[cfg(feature = "lexer")]
59 UnterminatedString,
60 #[cfg(feature = "lexer")]
62 UnterminatedExpression,
63 #[cfg(feature = "lexer")]
65 UnexpectedEof,
66 #[cfg(feature = "lexer")]
68 InvalidJsxSelfClosingTag,
69 #[cfg(feature = "lexer")]
71 UnterminatedJsxTag,
72 #[cfg(feature = "lexer")]
74 InvalidJsxClosingTag,
75 #[cfg(feature = "lexer")]
77 InvalidJsxAttribute,
78 #[cfg(feature = "lexer")]
80 UnterminatedCodeBlock,
81
82 #[cfg(feature = "lexer")]
84 EmptyFrontMatter,
85
86 #[cfg(feature = "parser")]
89 UnterminatedLink,
90 #[cfg(feature = "parser")]
92 UnterminatedImage,
93 #[cfg(feature = "parser")]
95 UnterminatedInlineCode,
96 #[cfg(feature = "parser")]
98 UnterminatedCodeBlockBlock,
99 #[cfg(feature = "parser")]
101 UnterminatedJsxOpenTag,
102 #[cfg(feature = "parser")]
104 UnterminatedJsxCloseTag,
105 #[cfg(feature = "parser")]
107 UnterminatedJsxExpression,
108 #[cfg(feature = "parser")]
110 UnterminatedMdComment,
111 #[cfg(feature = "parser")]
113 UnterminatedFrontmatter,
114 #[cfg(feature = "parser")]
116 MismatchedJsxCloseTag,
117 #[cfg(feature = "parser")]
119 TableShapeMismatch,
120 #[cfg(feature = "parser")]
122 StraySetextUnderline,
123 #[cfg(feature = "parser")]
125 MissingJsxAttributeValue,
126 #[cfg(feature = "parser")]
128 ListMarkerOverflow,
129
130 #[cfg(feature = "parser")]
132 EmptyFrontmatter,
133 #[cfg(feature = "parser")]
135 InvalidFrontmatterYaml,
136 #[cfg(feature = "parser")]
138 HeadingLevelClamped,
139 #[cfg(feature = "parser")]
141 RecoveredUnterminatedJsx,
142
143 #[cfg(feature = "transform")]
146 ImportFileNotFound,
147 #[cfg(feature = "transform")]
149 InvalidLineRange,
150 #[cfg(feature = "transform")]
152 RegistryIndexUnreadable,
153 #[cfg(feature = "transform")]
155 RegistryIndexMalformed,
156 #[cfg(feature = "transform")]
158 RegistryEntryNotFound,
159 #[cfg(feature = "transform")]
161 RegistrySourceUnreadable,
162 #[cfg(feature = "transform")]
164 ComponentSourceUnreadable,
165 #[cfg(feature = "transform")]
167 AssetCopyFailed,
168 #[cfg(feature = "transform")]
170 MermaidRenderFailed,
171
172 #[cfg(feature = "transform")]
174 MmdcUnavailable,
175 #[cfg(feature = "transform")]
177 MissingComponentAttr,
178 #[cfg(feature = "transform")]
180 AssetSourceMissing,
181 #[cfg(feature = "transform")]
185 BaseDirNotFound,
186
187 #[cfg(feature = "transform")]
191 KatexOpts,
192 #[cfg(feature = "transform")]
197 ThemeNotBundled,
198
199 #[cfg(feature = "codegen")]
202 MalformedJsxTagName,
203
204 #[cfg(feature = "codegen")]
207 MdxTableUnsupported,
208 #[cfg(feature = "codegen")]
211 HtmlExpressionDropped,
212
213 #[cfg(feature = "core")]
218 NoRootDir,
219 #[cfg(feature = "core")]
221 NoConfig,
222 #[cfg(feature = "core")]
224 NoCollections,
225 #[cfg(feature = "core")]
227 CollectionNotFound,
228 #[cfg(feature = "core")]
230 CollectionPatternNotFound,
231 #[cfg(feature = "core")]
233 CollectionSchemaNotFound,
234 #[cfg(feature = "core")]
236 InvalidConfig,
237 #[cfg(feature = "core")]
239 InvalidConfigPath,
240 #[cfg(feature = "core")]
242 ConfigExists,
243
244 IoRead,
250 IoWrite,
252 IoCreateDir,
254 JsonDeserialize,
256 JsonSerialize,
258 LockPoisoned,
260 IoRecoverable,
263
264 Custom { code: String, severity: Severity },
267}
268
269impl DiagnosticCode for Code {
270 fn code(&self) -> &str {
271 match self {
272 #[cfg(feature = "lexer")]
274 Self::InvalidCharacter => "E001",
275 #[cfg(feature = "lexer")]
276 Self::InvalidFrontMatter => "E002",
277 #[cfg(feature = "lexer")]
278 Self::UnterminatedString => "E003",
279 #[cfg(feature = "lexer")]
280 Self::UnterminatedExpression => "E004",
281 #[cfg(feature = "lexer")]
282 Self::UnexpectedEof => "E005",
283 #[cfg(feature = "lexer")]
284 Self::InvalidJsxSelfClosingTag => "E006",
285 #[cfg(feature = "lexer")]
286 Self::UnterminatedJsxTag => "E007",
287 #[cfg(feature = "lexer")]
288 Self::InvalidJsxClosingTag => "E008",
289 #[cfg(feature = "lexer")]
290 Self::InvalidJsxAttribute => "E009",
291 #[cfg(feature = "lexer")]
292 Self::UnterminatedCodeBlock => "E010",
293 #[cfg(feature = "lexer")]
294 Self::EmptyFrontMatter => "W001",
295
296 #[cfg(feature = "parser")]
298 Self::UnterminatedLink => "P001",
299 #[cfg(feature = "parser")]
300 Self::UnterminatedImage => "P002",
301 #[cfg(feature = "parser")]
302 Self::UnterminatedInlineCode => "P003",
303 #[cfg(feature = "parser")]
304 Self::UnterminatedCodeBlockBlock => "P004",
305 #[cfg(feature = "parser")]
306 Self::UnterminatedJsxOpenTag => "P005",
307 #[cfg(feature = "parser")]
308 Self::UnterminatedJsxCloseTag => "P006",
309 #[cfg(feature = "parser")]
310 Self::UnterminatedJsxExpression => "P007",
311 #[cfg(feature = "parser")]
312 Self::UnterminatedMdComment => "P008",
313 #[cfg(feature = "parser")]
314 Self::UnterminatedFrontmatter => "P009",
315 #[cfg(feature = "parser")]
316 Self::MismatchedJsxCloseTag => "P010",
317 #[cfg(feature = "parser")]
318 Self::TableShapeMismatch => "P011",
319 #[cfg(feature = "parser")]
320 Self::StraySetextUnderline => "P012",
321 #[cfg(feature = "parser")]
322 Self::MissingJsxAttributeValue => "P013",
323 #[cfg(feature = "parser")]
324 Self::ListMarkerOverflow => "P014",
325 #[cfg(feature = "parser")]
326 Self::EmptyFrontmatter => "PW001",
327 #[cfg(feature = "parser")]
328 Self::InvalidFrontmatterYaml => "PW002",
329 #[cfg(feature = "parser")]
330 Self::HeadingLevelClamped => "PW003",
331 #[cfg(feature = "parser")]
332 Self::RecoveredUnterminatedJsx => "PW004",
333
334 #[cfg(feature = "transform")]
336 Self::ImportFileNotFound => "T001",
337 #[cfg(feature = "transform")]
338 Self::InvalidLineRange => "T002",
339 #[cfg(feature = "transform")]
340 Self::RegistryIndexUnreadable => "T003",
341 #[cfg(feature = "transform")]
342 Self::RegistryIndexMalformed => "T004",
343 #[cfg(feature = "transform")]
344 Self::RegistryEntryNotFound => "T005",
345 #[cfg(feature = "transform")]
346 Self::RegistrySourceUnreadable => "T006",
347 #[cfg(feature = "transform")]
348 Self::ComponentSourceUnreadable => "T007",
349 #[cfg(feature = "transform")]
350 Self::AssetCopyFailed => "T008",
351 #[cfg(feature = "transform")]
352 Self::MermaidRenderFailed => "T009",
353 #[cfg(feature = "transform")]
354 Self::MmdcUnavailable => "TW001",
355 #[cfg(feature = "transform")]
356 Self::MissingComponentAttr => "TW002",
357 #[cfg(feature = "transform")]
358 Self::AssetSourceMissing => "TW003",
359 #[cfg(feature = "transform")]
360 Self::BaseDirNotFound => "TW004",
361 #[cfg(feature = "transform")]
362 Self::ThemeNotBundled => "TW005",
363 #[cfg(feature = "transform")]
364 Self::KatexOpts => "TW006",
365
366 #[cfg(feature = "codegen")]
367 Self::MalformedJsxTagName => "G001",
368 #[cfg(feature = "codegen")]
369 Self::MdxTableUnsupported => "GW001",
370 #[cfg(feature = "codegen")]
371 Self::HtmlExpressionDropped => "GW002",
372
373 #[cfg(feature = "core")]
375 Self::NoRootDir => "C001",
376 #[cfg(feature = "core")]
377 Self::NoConfig => "C002",
378 #[cfg(feature = "core")]
379 Self::NoCollections => "C003",
380 #[cfg(feature = "core")]
381 Self::CollectionNotFound => "C004",
382 #[cfg(feature = "core")]
383 Self::CollectionPatternNotFound => "C005",
384 #[cfg(feature = "core")]
385 Self::CollectionSchemaNotFound => "C006",
386 #[cfg(feature = "core")]
387 Self::InvalidConfig => "C007",
388 #[cfg(feature = "core")]
389 Self::InvalidConfigPath => "C008",
390 #[cfg(feature = "core")]
391 Self::ConfigExists => "CW001",
392
393 Self::IoRead => "S001",
395 Self::IoWrite => "S002",
396 Self::IoCreateDir => "S003",
397 Self::JsonDeserialize => "S004",
398 Self::JsonSerialize => "S005",
399 Self::LockPoisoned => "S006",
400 Self::IoRecoverable => "SW001",
401
402 Self::Custom { code, .. } => code.as_str(),
403 }
404 }
405
406 fn severity(&self) -> Severity {
407 match self {
408 #[cfg(feature = "lexer")]
410 Self::InvalidCharacter
411 | Self::InvalidFrontMatter
412 | Self::UnterminatedString
413 | Self::UnterminatedExpression
414 | Self::UnexpectedEof
415 | Self::InvalidJsxSelfClosingTag
416 | Self::UnterminatedJsxTag
417 | Self::InvalidJsxClosingTag
418 | Self::InvalidJsxAttribute
419 | Self::UnterminatedCodeBlock => Severity::Error,
420 #[cfg(feature = "lexer")]
421 Self::EmptyFrontMatter => Severity::Warning,
422
423 #[cfg(feature = "parser")]
425 Self::UnterminatedLink
426 | Self::UnterminatedImage
427 | Self::UnterminatedInlineCode
428 | Self::UnterminatedCodeBlockBlock
429 | Self::UnterminatedJsxOpenTag
430 | Self::UnterminatedJsxCloseTag
431 | Self::UnterminatedJsxExpression
432 | Self::UnterminatedMdComment
433 | Self::UnterminatedFrontmatter
434 | Self::MismatchedJsxCloseTag
435 | Self::TableShapeMismatch
436 | Self::StraySetextUnderline
437 | Self::MissingJsxAttributeValue
438 | Self::ListMarkerOverflow => Severity::Error,
439 #[cfg(feature = "parser")]
440 Self::EmptyFrontmatter
441 | Self::InvalidFrontmatterYaml
442 | Self::HeadingLevelClamped
443 | Self::RecoveredUnterminatedJsx => Severity::Warning,
444
445 #[cfg(feature = "transform")]
447 Self::ImportFileNotFound
448 | Self::InvalidLineRange
449 | Self::RegistryIndexUnreadable
450 | Self::RegistryIndexMalformed
451 | Self::RegistryEntryNotFound
452 | Self::RegistrySourceUnreadable
453 | Self::ComponentSourceUnreadable
454 | Self::AssetCopyFailed
455 | Self::MermaidRenderFailed => Severity::Error,
456 #[cfg(feature = "transform")]
457 Self::MmdcUnavailable
458 | Self::MissingComponentAttr
459 | Self::AssetSourceMissing
460 | Self::BaseDirNotFound
461 | Self::ThemeNotBundled
462 | Self::KatexOpts => Severity::Warning,
463
464 #[cfg(feature = "codegen")]
465 Self::MalformedJsxTagName => Severity::Error,
466 #[cfg(feature = "codegen")]
467 Self::MdxTableUnsupported | Self::HtmlExpressionDropped => Severity::Warning,
468
469 #[cfg(feature = "core")]
471 Self::NoRootDir
472 | Self::NoConfig
473 | Self::NoCollections
474 | Self::CollectionNotFound
475 | Self::CollectionPatternNotFound
476 | Self::CollectionSchemaNotFound
477 | Self::InvalidConfig
478 | Self::InvalidConfigPath => Severity::Error,
479 #[cfg(feature = "core")]
480 Self::ConfigExists => Severity::Warning,
481
482 Self::IoRead
484 | Self::IoWrite
485 | Self::IoCreateDir
486 | Self::JsonDeserialize
487 | Self::JsonSerialize
488 | Self::LockPoisoned => Severity::Error,
489 Self::IoRecoverable => Severity::Warning,
490
491 Self::Custom { severity, .. } => *severity,
492 }
493 }
494}