Skip to main content

croma_core/
diagnostic.rs

1#[derive(Debug, Clone, PartialEq, Eq)]
2pub struct Diagnostic {
3    pub severity: Severity,
4    pub code: &'static str,
5    pub message: String,
6    pub span: Span,
7    pub spec_reference: Option<SpecReference>,
8    pub recovery_note: Option<RecoveryNote>,
9}
10
11impl Diagnostic {
12    pub fn new(
13        severity: Severity,
14        code: &'static str,
15        message: impl Into<String>,
16        span: Span,
17    ) -> Self {
18        Self {
19            severity,
20            code,
21            message: message.into(),
22            span,
23            spec_reference: None,
24            recovery_note: None,
25        }
26    }
27
28    pub fn with_spec_reference(mut self, spec_reference: SpecReference) -> Self {
29        self.spec_reference = Some(spec_reference);
30        self
31    }
32
33    pub fn with_recovery_note(mut self, recovery_note: RecoveryNote) -> Self {
34        self.recovery_note = Some(recovery_note);
35        self
36    }
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct SpecReference {
41    pub label: String,
42    pub url: Option<String>,
43}
44
45impl SpecReference {
46    pub fn new(label: impl Into<String>) -> Self {
47        Self {
48            label: label.into(),
49            url: None,
50        }
51    }
52
53    pub fn with_url(mut self, url: impl Into<String>) -> Self {
54        self.url = Some(url.into());
55        self
56    }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct RecoveryNote {
61    pub message: String,
62}
63
64impl RecoveryNote {
65    pub fn new(message: impl Into<String>) -> Self {
66        Self {
67            message: message.into(),
68        }
69    }
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
73pub enum Severity {
74    Error,
75    Warning,
76    Info,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
80pub struct Span {
81    pub start: usize,
82    pub end: usize,
83}
84
85impl Span {
86    pub fn new(start: usize, end: usize) -> Self {
87        Self { start, end }
88    }
89
90    pub fn len(self) -> usize {
91        self.end.saturating_sub(self.start)
92    }
93
94    pub fn is_empty(self) -> bool {
95        self.start == self.end
96    }
97
98    pub fn contains(self, offset: usize) -> bool {
99        self.start <= offset && offset < self.end
100    }
101
102    pub fn contains_span(self, span: Span) -> bool {
103        self.start <= span.start && span.end <= self.end
104    }
105}
106
107#[cfg(test)]
108#[path = "diagnostic_tests.rs"]
109mod tests;