rune/workspace/
diagnostics.rs

1use crate::alloc::{self, Vec};
2use crate::workspace::WorkspaceError;
3use crate::SourceId;
4
5/// A fatal diagnostic in a workspace.
6#[derive(Debug)]
7pub struct FatalDiagnostic {
8    source_id: SourceId,
9    error: WorkspaceError,
10}
11
12impl FatalDiagnostic {
13    /// Get source id of the diagnostic.
14    pub fn source_id(&self) -> SourceId {
15        self.source_id
16    }
17
18    /// Access the underlying workspace error.
19    pub fn error(&self) -> &WorkspaceError {
20        &self.error
21    }
22}
23
24/// A single workspace diagnostic.
25#[derive(Debug)]
26#[non_exhaustive]
27pub enum Diagnostic {
28    /// An error in a workspace.
29    Fatal(FatalDiagnostic),
30}
31
32/// Diagnostics emitted about a workspace.
33#[derive(Default)]
34pub struct Diagnostics {
35    pub(crate) diagnostics: Vec<Diagnostic>,
36}
37
38impl Diagnostics {
39    /// Access underlying diagnostics.
40    pub fn diagnostics(&self) -> &[Diagnostic] {
41        &self.diagnostics
42    }
43
44    /// Test if diagnostics has errors.
45    pub fn has_errors(&self) -> bool {
46        self.diagnostics
47            .iter()
48            .any(|e| matches!(e, Diagnostic::Fatal(..)))
49    }
50
51    /// Test if diagnostics is empty.
52    pub fn is_empty(&self) -> bool {
53        self.diagnostics.is_empty()
54    }
55
56    /// Report a single workspace error.
57    pub(crate) fn fatal(
58        &mut self,
59        source_id: SourceId,
60        error: WorkspaceError,
61    ) -> alloc::Result<()> {
62        self.diagnostics
63            .try_push(Diagnostic::Fatal(FatalDiagnostic { source_id, error }))
64    }
65}
66
67impl Diagnostics {
68    /// Construct an empty diagnostics container.
69    pub fn new() -> Self {
70        Self::default()
71    }
72}