compose_lens/diagnostic/
mod.rs1use crate::source::SourceSpan;
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct DiagnosticCode(&'static str);
9
10impl DiagnosticCode {
11 #[must_use]
13 pub const fn new(value: &'static str) -> Self {
14 Self(value)
15 }
16
17 #[must_use]
19 pub const fn as_str(self) -> &'static str {
20 self.0
21 }
22}
23
24impl fmt::Display for DiagnosticCode {
25 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
26 formatter.write_str(self.0)
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
32pub enum Severity {
33 Error,
35 Warning,
37 Note,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43pub enum LabelKind {
44 Primary,
46 Secondary,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct DiagnosticLabel {
53 kind: LabelKind,
54 span: SourceSpan,
55 message: String,
56}
57
58impl DiagnosticLabel {
59 #[must_use]
61 pub fn primary(span: SourceSpan, message: impl Into<String>) -> Self {
62 Self {
63 kind: LabelKind::Primary,
64 span,
65 message: message.into(),
66 }
67 }
68
69 #[must_use]
71 pub fn secondary(span: SourceSpan, message: impl Into<String>) -> Self {
72 Self {
73 kind: LabelKind::Secondary,
74 span,
75 message: message.into(),
76 }
77 }
78
79 #[must_use]
81 pub const fn kind(&self) -> LabelKind {
82 self.kind
83 }
84
85 #[must_use]
87 pub const fn span(&self) -> SourceSpan {
88 self.span
89 }
90
91 #[must_use]
93 pub fn message(&self) -> &str {
94 &self.message
95 }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
100pub struct Diagnostic {
101 code: DiagnosticCode,
102 severity: Severity,
103 message: String,
104 labels: Vec<DiagnosticLabel>,
105 notes: Vec<String>,
106}
107
108impl Diagnostic {
109 #[must_use]
111 pub fn new(code: DiagnosticCode, severity: Severity, message: impl Into<String>) -> Self {
112 Self {
113 code,
114 severity,
115 message: message.into(),
116 labels: Vec::new(),
117 notes: Vec::new(),
118 }
119 }
120
121 #[must_use]
123 pub fn with_label(mut self, label: DiagnosticLabel) -> Self {
124 self.labels.push(label);
125 self
126 }
127
128 #[must_use]
130 pub fn with_note(mut self, note: impl Into<String>) -> Self {
131 self.notes.push(note.into());
132 self
133 }
134
135 #[must_use]
137 pub const fn code(&self) -> DiagnosticCode {
138 self.code
139 }
140
141 #[must_use]
143 pub const fn severity(&self) -> Severity {
144 self.severity
145 }
146
147 #[must_use]
149 pub fn message(&self) -> &str {
150 &self.message
151 }
152
153 #[must_use]
155 pub fn labels(&self) -> &[DiagnosticLabel] {
156 &self.labels
157 }
158
159 #[must_use]
161 pub fn notes(&self) -> &[String] {
162 &self.notes
163 }
164}