use owo_colors::OwoColorize;
use std::fmt::Display;
use crate::{diagnostic_report::FileNameReport, spans::Span};
pub trait Issue: Sized {
fn diagnostic(&self) -> Diagnostic;
}
#[derive(Default, Clone, Eq, PartialEq, Debug)]
pub struct Diagnostic {
pub name: &'static str,
pub severity: Severity,
pub span: Span,
pub message: String,
}
impl FileNameReport for Diagnostic {
fn make_file_name_report(&self, filename: &str) -> String {
let start = self.span.start;
format!(
"{}: {} in {}:{}:{}",
self.severity.coloured_display().bold(),
self.message.bold(),
filename,
start.row + 1,
start.column + 1,
)
}
}
impl Display for Diagnostic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let start = self.span.start;
let end = self.span.end;
write!(
f,
"{}: {}:{}-{}:{},{}",
self.severity,
self.message,
start.row + 1,
start.column + 1,
end.row + 1,
end.column + 1
)
}
}
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
pub enum Severity {
Hint,
Info,
#[default]
Warning,
Error,
}
impl From<Severity> for lsp_types::DiagnosticSeverity {
fn from(value: Severity) -> Self {
use lsp_types::DiagnosticSeverity as DS;
match value {
Severity::Hint => DS::HINT,
Severity::Info => DS::INFORMATION,
Severity::Warning => DS::WARNING,
Severity::Error => DS::ERROR,
}
}
}
impl Severity {
fn coloured_display(&self) -> String {
let repr = self.to_string().to_lowercase();
match self {
Self::Hint => format!("{}", repr.bright_green()),
Self::Info => format!("{}", repr.bright_blue()),
Self::Warning => format!("{}", repr.bright_yellow()),
Self::Error => format!("{}", repr.bright_red()),
}
}
}
impl Display for Severity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Hint => write!(f, "HINT"),
Self::Info => write!(f, "INFO"),
Self::Warning => write!(f, "WARNING"),
Self::Error => write!(f, "ERROR"),
}
}
}
impl From<Diagnostic> for lsp_types::Diagnostic {
fn from(value: Diagnostic) -> Self {
let Diagnostic {
severity,
span,
message,
..
} = value;
lsp_types::Diagnostic {
range: span.into_lsp_types(),
severity: Some(severity.into()),
source: Some("lammps-analyser".into()),
message,
..Default::default()
}
}
}