///|
/// How serious a diagnostic is. A file with an `Error` is rejected; a
/// `Warning` does not stop parsing.
pub(all) enum Severity {
Error
Warning
} derive(Eq, Debug, Hash)
///|
/// A secondary span with the text shown under it ("the structure started
/// here").
pub(all) struct Label {
span : @span.Span
text : String
} derive(Eq, Debug)
///|
/// A problem found while scanning or parsing, with everything a rich
/// report needs: a `title` in capitals (`UNFINISHED SHAPE`), a one-line
/// `message` under the primary `span`, secondary `labels`, `notes` in the
/// first person, an optional `hint` and an optional correct `example`.
/// Immutable: `with_context` returns a new value.
pub(all) struct Diagnostic {
code : String
severity : Severity
title : String
message : String
span : @span.Span
labels : ArrayView[Label]
notes : ArrayView[String]
hint : String?
example : String?
} derive(Eq, Debug)
///|
/// Build a diagnostic; the optional parts default to empty lists and `None`.
pub fn Diagnostic::new(
code~ : String,
severity~ : Severity,
title~ : String,
message~ : String,
span~ : @span.Span,
labels? : Array[Label],
notes? : Array[String],
hint? : String,
example? : String,
) -> Diagnostic {
{
code,
severity,
title,
message,
span,
labels: labels.unwrap_or([])[:],
notes: notes.unwrap_or([])[:],
hint,
example,
}
}
///|
/// Whether the severity is `Error`.
pub fn Diagnostic::is_error(self : Diagnostic) -> Bool {
self.severity == Error
}
///|
/// A copy with `label` as the first label and `note` as the first note.
pub fn Diagnostic::with_context(
self : Diagnostic,
label : Label,
note : String,
) -> Diagnostic {
let labels = [label]
labels.append(self.labels.to_owned())
let notes = [note]
notes.append(self.notes.to_owned())
{ ..self, labels: labels[:], notes: notes[:], }
}