yaml_rt_core/
diagnostic.rs1use std::fmt;
2
3use crate::{LineCol, Source, Span};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct YamlError {
8 pub diagnostic: Diagnostic,
10}
11
12impl YamlError {
13 #[must_use]
15 pub const fn new(diagnostic: Diagnostic) -> Self {
16 Self { diagnostic }
17 }
18
19 #[must_use]
22 pub fn with_position_from(mut self, source: &Source) -> Self {
23 if self.diagnostic.position.is_none() {
24 self.diagnostic.position = Some(source.diagnostic_position(&self.diagnostic));
25 }
26 self
27 }
28}
29
30impl fmt::Display for YamlError {
31 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32 self.diagnostic.fmt(formatter)
33 }
34}
35
36impl std::error::Error for YamlError {}
37
38#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct Diagnostic {
41 pub kind: DiagnosticKind,
43 pub message: String,
45 pub span: Span,
47 pub position: Option<LineCol>,
49 pub expected: Vec<String>,
51 pub notes: Vec<String>,
53}
54
55impl Diagnostic {
56 #[must_use]
58 pub fn new(kind: DiagnosticKind, message: impl Into<String>, span: Span) -> Self {
59 Self {
60 kind,
61 message: message.into(),
62 span,
63 position: None,
64 expected: Vec::new(),
65 notes: Vec::new(),
66 }
67 }
68
69 #[must_use]
71 pub const fn with_position(mut self, position: LineCol) -> Self {
72 self.position = Some(position);
73 self
74 }
75
76 #[must_use]
78 pub fn with_expected(mut self, expected: impl Into<String>) -> Self {
79 self.expected.push(expected.into());
80 self
81 }
82
83 #[must_use]
85 pub fn with_note(mut self, note: impl Into<String>) -> Self {
86 self.notes.push(note.into());
87 self
88 }
89}
90
91impl fmt::Display for Diagnostic {
92 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
93 write!(formatter, "{:?}: {}", self.kind, self.message)?;
94
95 if let Some(position) = self.position {
96 write!(formatter, " at {}:{}", position.line, position.column)?;
97 }
98
99 if !self.expected.is_empty() {
100 write!(formatter, " (expected: {})", self.expected.join(", "))?;
101 }
102
103 for note in &self.notes {
104 write!(formatter, "\nnote: {note}")?;
105 }
106
107 Ok(())
108 }
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum DiagnosticKind {
114 Source,
116 Lexer,
118 Parser,
120 Semantic,
122 Typed,
124 Emitter,
126}
127
128pub type ParseError = YamlError;