use std::fmt;
use std::path::PathBuf;
use colored::*;
use crate::parser::utils::{next_new_line, previous_new_line, replicate};
use crate::parser::Position;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum WarningType {
ConsecutiveStars,
}
impl WarningType {
pub fn title(self) -> &'static str {
match self {
WarningType::ConsecutiveStars => "empty bold section",
}
}
pub fn detail(self) -> &'static str {
match self {
WarningType::ConsecutiveStars => "this will be ignored",
}
}
pub fn note(self) -> Option<&'static str> {
match self {
WarningType::ConsecutiveStars => {
Some("to use bold, you should use single stars, e.g. '*this is bold*'")
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EmptyWarning {
pub position: Position,
pub ty: WarningType,
}
#[derive(Debug)]
pub struct Warnings {
pub path: PathBuf,
pub content: String,
pub warnings: Vec<EmptyWarning>,
}
impl fmt::Display for Warnings {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for warning in &self.warnings {
let start = previous_new_line(&self.content, warning.position.offset);
let end = next_new_line(&self.content, warning.position.offset);
let line = warning.position.line;
let column = warning.position.column;
let line_number = format!("{} ", line);
let space = replicate(' ', line_number.len() - 1);
let margin = replicate(' ', column);
let hats = replicate('^', 1);
writeln!(
fmt,
"{}{}",
"warning: ".bold().yellow(),
warning.ty.title().bold()
)?;
writeln!(
fmt,
"{}{} {}:{}:{}",
space,
"-->".bold().blue(),
self.path.display(),
line,
column
)?;
writeln!(fmt, "{} {}", space, "|".blue().bold())?;
writeln!(
fmt,
"{} {}",
&format!("{}|", line_number).blue().bold(),
&self.content[start..end]
)?;
writeln!(
fmt,
"{} {}{}{} {}",
space,
"|".blue().bold(),
margin,
hats.bold().yellow(),
warning.ty.detail().bold().yellow()
)?;
writeln!(fmt, "{} {}", space, "|".blue().bold())?;
if let Some(note) = warning.ty.note() {
writeln!(
fmt,
"{} {} {}{}",
space,
"=".blue().bold(),
"note: ".bold(),
note
)?;
}
}
Ok(())
}
}