summaryrefslogtreecommitdiffstats
path: root/third_party/rust/codespan-reporting/src/diagnostic.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/codespan-reporting/src/diagnostic.rs')
-rw-r--r--third_party/rust/codespan-reporting/src/diagnostic.rs209
1 files changed, 209 insertions, 0 deletions
diff --git a/third_party/rust/codespan-reporting/src/diagnostic.rs b/third_party/rust/codespan-reporting/src/diagnostic.rs
new file mode 100644
index 0000000000..c1f98bd435
--- /dev/null
+++ b/third_party/rust/codespan-reporting/src/diagnostic.rs
@@ -0,0 +1,209 @@
+//! Diagnostic data structures.
+
+#[cfg(feature = "serialization")]
+use serde::{Deserialize, Serialize};
+use std::ops::Range;
+
+/// A severity level for diagnostic messages.
+///
+/// These are ordered in the following way:
+///
+/// ```rust
+/// use codespan_reporting::diagnostic::Severity;
+///
+/// assert!(Severity::Bug > Severity::Error);
+/// assert!(Severity::Error > Severity::Warning);
+/// assert!(Severity::Warning > Severity::Note);
+/// assert!(Severity::Note > Severity::Help);
+/// ```
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
+pub enum Severity {
+ /// An unexpected bug.
+ Bug,
+ /// An error.
+ Error,
+ /// A warning.
+ Warning,
+ /// A note.
+ Note,
+ /// A help message.
+ Help,
+}
+
+impl Severity {
+ /// We want bugs to be the maximum severity, errors next, etc...
+ fn to_cmp_int(self) -> u8 {
+ match self {
+ Severity::Bug => 5,
+ Severity::Error => 4,
+ Severity::Warning => 3,
+ Severity::Note => 2,
+ Severity::Help => 1,
+ }
+ }
+}
+
+impl PartialOrd for Severity {
+ fn partial_cmp(&self, other: &Severity) -> Option<std::cmp::Ordering> {
+ u8::partial_cmp(&self.to_cmp_int(), &other.to_cmp_int())
+ }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd)]
+#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
+pub enum LabelStyle {
+ /// Labels that describe the primary cause of a diagnostic.
+ Primary,
+ /// Labels that provide additional context for a diagnostic.
+ Secondary,
+}
+
+/// A label describing an underlined region of code associated with a diagnostic.
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
+pub struct Label<FileId> {
+ /// The style of the label.
+ pub style: LabelStyle,
+ /// The file that we are labelling.
+ pub file_id: FileId,
+ /// The range in bytes we are going to include in the final snippet.
+ pub range: Range<usize>,
+ /// An optional message to provide some additional information for the
+ /// underlined code. These should not include line breaks.
+ pub message: String,
+}
+
+impl<FileId> Label<FileId> {
+ /// Create a new label.
+ pub fn new(
+ style: LabelStyle,
+ file_id: FileId,
+ range: impl Into<Range<usize>>,
+ ) -> Label<FileId> {
+ Label {
+ style,
+ file_id,
+ range: range.into(),
+ message: String::new(),
+ }
+ }
+
+ /// Create a new label with a style of [`LabelStyle::Primary`].
+ ///
+ /// [`LabelStyle::Primary`]: LabelStyle::Primary
+ pub fn primary(file_id: FileId, range: impl Into<Range<usize>>) -> Label<FileId> {
+ Label::new(LabelStyle::Primary, file_id, range)
+ }
+
+ /// Create a new label with a style of [`LabelStyle::Secondary`].
+ ///
+ /// [`LabelStyle::Secondary`]: LabelStyle::Secondary
+ pub fn secondary(file_id: FileId, range: impl Into<Range<usize>>) -> Label<FileId> {
+ Label::new(LabelStyle::Secondary, file_id, range)
+ }
+
+ /// Add a message to the diagnostic.
+ pub fn with_message(mut self, message: impl Into<String>) -> Label<FileId> {
+ self.message = message.into();
+ self
+ }
+}
+
+/// Represents a diagnostic message that can provide information like errors and
+/// warnings to the user.
+///
+/// The position of a Diagnostic is considered to be the position of the [`Label`] that has the earliest starting position and has the highest style which appears in all the labels of the diagnostic.
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
+pub struct Diagnostic<FileId> {
+ /// The overall severity of the diagnostic
+ pub severity: Severity,
+ /// An optional code that identifies this diagnostic.
+ pub code: Option<String>,
+ /// The main message associated with this diagnostic.
+ ///
+ /// These should not include line breaks, and in order support the 'short'
+ /// diagnostic display mod, the message should be specific enough to make
+ /// sense on its own, without additional context provided by labels and notes.
+ pub message: String,
+ /// Source labels that describe the cause of the diagnostic.
+ /// The order of the labels inside the vector does not have any meaning.
+ /// The labels are always arranged in the order they appear in the source code.
+ pub labels: Vec<Label<FileId>>,
+ /// Notes that are associated with the primary cause of the diagnostic.
+ /// These can include line breaks for improved formatting.
+ pub notes: Vec<String>,
+}
+
+impl<FileId> Diagnostic<FileId> {
+ /// Create a new diagnostic.
+ pub fn new(severity: Severity) -> Diagnostic<FileId> {
+ Diagnostic {
+ severity,
+ code: None,
+ message: String::new(),
+ labels: Vec::new(),
+ notes: Vec::new(),
+ }
+ }
+
+ /// Create a new diagnostic with a severity of [`Severity::Bug`].
+ ///
+ /// [`Severity::Bug`]: Severity::Bug
+ pub fn bug() -> Diagnostic<FileId> {
+ Diagnostic::new(Severity::Bug)
+ }
+
+ /// Create a new diagnostic with a severity of [`Severity::Error`].
+ ///
+ /// [`Severity::Error`]: Severity::Error
+ pub fn error() -> Diagnostic<FileId> {
+ Diagnostic::new(Severity::Error)
+ }
+
+ /// Create a new diagnostic with a severity of [`Severity::Warning`].
+ ///
+ /// [`Severity::Warning`]: Severity::Warning
+ pub fn warning() -> Diagnostic<FileId> {
+ Diagnostic::new(Severity::Warning)
+ }
+
+ /// Create a new diagnostic with a severity of [`Severity::Note`].
+ ///
+ /// [`Severity::Note`]: Severity::Note
+ pub fn note() -> Diagnostic<FileId> {
+ Diagnostic::new(Severity::Note)
+ }
+
+ /// Create a new diagnostic with a severity of [`Severity::Help`].
+ ///
+ /// [`Severity::Help`]: Severity::Help
+ pub fn help() -> Diagnostic<FileId> {
+ Diagnostic::new(Severity::Help)
+ }
+
+ /// Set the error code of the diagnostic.
+ pub fn with_code(mut self, code: impl Into<String>) -> Diagnostic<FileId> {
+ self.code = Some(code.into());
+ self
+ }
+
+ /// Set the message of the diagnostic.
+ pub fn with_message(mut self, message: impl Into<String>) -> Diagnostic<FileId> {
+ self.message = message.into();
+ self
+ }
+
+ /// Add some labels to the diagnostic.
+ pub fn with_labels(mut self, mut labels: Vec<Label<FileId>>) -> Diagnostic<FileId> {
+ self.labels.append(&mut labels);
+ self
+ }
+
+ /// Add some notes to the diagnostic.
+ pub fn with_notes(mut self, mut notes: Vec<String>) -> Diagnostic<FileId> {
+ self.notes.append(&mut notes);
+ self
+ }
+}