use core::fmt::Display;
use serde::{Deserialize, Serialize};
use yansi::Paint;
use crate::position::Position;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Diagnostic {
pub filename: Option<String>,
pub start: Position,
pub end: Position,
pub code: String,
pub message: String,
}
impl Diagnostic {
pub fn new<S: Into<String>>(
filename: Option<S>,
start: Position,
end: Position,
code: String,
message: String,
) -> Self {
Self {
filename: filename.map(Into::into),
start,
end,
code,
message,
}
}
}
impl Display for Diagnostic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let filename = self.filename.as_deref().unwrap_or("<stdin>");
let line = self.start.line;
let column = self.start.column;
let buf = format!(
"{}\0{}\0{}\0{}\0{}",
filename,
line + 1,
column + 1,
self.code,
self.message
);
let tokens: Vec<&str> = buf.split('\0').collect();
let colon = ":".cyan();
let filename = tokens[0].white().bold();
let line = tokens[1];
let column = tokens[2];
let code = tokens[3].yellow();
let message = tokens[4];
write!(
f,
"{}{colon}{}{colon}{}{colon} {} {}",
filename, line, column, code, message
)
}
}