#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum Severity {
Bug,
Error,
Warning,
Note,
Help,
}
impl Severity {
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 {
Primary,
Secondary,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Label<FileId> {
pub style: LabelStyle,
pub file_id: FileId,
pub range: Range<usize>,
pub message: String,
}
impl<FileId> Label<FileId> {
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(),
}
}
pub fn primary(file_id: FileId, range: impl Into<Range<usize>>) -> Label<FileId> {
Label::new(LabelStyle::Primary, file_id, range)
}
pub fn secondary(file_id: FileId, range: impl Into<Range<usize>>) -> Label<FileId> {
Label::new(LabelStyle::Secondary, file_id, range)
}
pub fn with_message(mut self, message: impl Into<String>) -> Label<FileId> {
self.message = message.into();
self
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Diagnostic<FileId> {
pub severity: Severity,
pub code: Option<String>,
pub message: String,
pub labels: Vec<Label<FileId>>,
pub notes: Vec<String>,
}
impl<FileId> Diagnostic<FileId> {
pub fn new(severity: Severity) -> Diagnostic<FileId> {
Diagnostic {
severity,
code: None,
message: String::new(),
labels: Vec::new(),
notes: Vec::new(),
}
}
pub fn bug() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Bug)
}
pub fn error() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Error)
}
pub fn warning() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Warning)
}
pub fn note() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Note)
}
pub fn help() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Help)
}
pub fn with_code(mut self, code: impl Into<String>) -> Diagnostic<FileId> {
self.code = Some(code.into());
self
}
pub fn with_message(mut self, message: impl Into<String>) -> Diagnostic<FileId> {
self.message = message.into();
self
}
pub fn with_labels(mut self, mut labels: Vec<Label<FileId>>) -> Diagnostic<FileId> {
self.labels.append(&mut labels);
self
}
pub fn with_notes(mut self, mut notes: Vec<String>) -> Diagnostic<FileId> {
self.notes.append(&mut notes);
self
}
}