use super::{DiagnosticKind, Error, Lint, Note};
use crate::slice_file::Span;
#[derive(Debug)]
pub struct Diagnostic {
pub kind: DiagnosticKind,
pub span: Option<Span>,
pub scope: Option<String>,
pub notes: Vec<Note>,
pub plugin: Option<String>,
}
impl Diagnostic {
pub fn new(kind: DiagnosticKind) -> Self {
Diagnostic {
kind,
span: None,
scope: None,
notes: Vec::new(),
plugin: None,
}
}
pub fn from_error(error: Error) -> Self {
Self::new(DiagnosticKind::Error(error))
}
pub fn from_lint(lint: Lint) -> Self {
Self::new(DiagnosticKind::Lint(lint))
}
pub fn from_info(message: impl Into<String>) -> Self {
Self::new(DiagnosticKind::Info(message.into()))
}
pub fn message(&self) -> String {
match &self.kind {
DiagnosticKind::Error(error) => error.message(),
DiagnosticKind::Lint(lint) => lint.message(),
DiagnosticKind::Info(message) => message.clone(),
}
}
pub fn code(&self) -> &str {
match &self.kind {
DiagnosticKind::Error(error) => error.error_code(),
DiagnosticKind::Lint(lint) => lint.lint_name(),
DiagnosticKind::Info(_) => "",
}
}
pub fn set_span(mut self, span: &Span) -> Self {
assert!(self.span.is_none()); self.span = Some(span.to_owned());
self
}
pub fn set_scope(mut self, scope: impl Into<String>) -> Self {
assert!(self.scope.is_none()); self.scope = Some(scope.into());
self
}
pub fn add_note(mut self, message: impl Into<String>, span: Option<&Span>) -> Self {
self.notes.push(Note {
message: message.into(),
span: span.cloned(),
});
self
}
pub fn push_into(self, diagnostics: &mut Diagnostics) {
diagnostics.0.push(self);
}
}
#[derive(Debug, Default)]
pub struct Diagnostics(Vec<Diagnostic>);
impl Diagnostics {
pub fn new() -> Self {
Self::default()
}
pub fn has_errors(&self) -> bool {
let mut diagnostics = self.0.iter();
diagnostics.any(|diagnostic| matches!(diagnostic.kind, DiagnosticKind::Error(_)))
}
pub fn into_inner(self) -> Vec<Diagnostic> {
self.0
}
}
impl std::ops::Deref for Diagnostics {
type Target = Vec<Diagnostic>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for Diagnostics {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}