#![allow(dead_code)]
use owo_colors::OwoColorize;
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)]
pub enum MessageType {
Info,
Warning,
Error,
Todo,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)]
pub enum MessageLocation<'a> {
None,
File(&'a str, MessageSpan<'a>, Option<(usize, usize)>),
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)]
pub struct MessageSpan<'a> {
text: &'a str,
start: usize,
end: usize,
}
impl<'a> MessageSpan<'a> {
pub fn new(text: &'a str, start: usize) -> Self {
return Self {
text,
start,
end: start + text.chars().into_iter().collect::<Vec<char>>().len(),
};
}
pub fn empty() -> Self {
return Self {
text: "",
start: 0,
end: 1,
};
}
pub fn is_empty(&self) -> bool {
return *self == Self::empty();
}
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)]
pub struct Message<'a> {
msg: &'a str,
msg_type: MessageType,
location: MessageLocation<'a>,
}
impl<'a> Message<'a> {
pub fn new(msg: &'a str, msg_type: MessageType, location: MessageLocation<'a>) -> Self {
return Self {
msg,
msg_type,
location,
};
}
pub fn print(&self) {
match self.location {
MessageLocation::None => {
println!(
"{} {} {}",
colorize("COMPILER", self.msg_type).on_black().reversed().bold(),
"::".bright_black().bold(),
self.msg.bold(),
);
},
MessageLocation::File(file, area, problem_area) => {
let tab = " ";
println!(
"{} {} {}",
colorize(file, self.msg_type).on_black().reversed().bold(),
"::".bright_black().bold(),
self.msg.bold(),
);
if area.is_empty() {
return;
}
let length = area.end - area.start;
println!(
"{tab}{tab}{} (start: {} | end: {} | length: {})",
area.text,
colorize(&area.start.to_string(), self.msg_type).bold(),
colorize(&area.end.to_string(), self.msg_type).bold(),
colorize(&length.to_string(), self.msg_type).bold(),
);
if let Some(problem_area) = problem_area {
let start = problem_area.0 - area.start;
let end = (problem_area.1 - problem_area.0) + start;
print!("{tab}{tab}");
for i in 0..length {
if i >= start && i < end {
print!("{}", colorize("^", self.msg_type).bold());
}
else {
print!(" ");
}
}
println!("");
}
},
};
}
}
fn colorize(text: &str, msg_type: MessageType) -> String {
return match msg_type {
MessageType::Info => text.bright_green().to_string(),
MessageType::Warning => text.bright_yellow().to_string(),
MessageType::Error => text.bright_red().to_string(),
MessageType::Todo => text.bright_cyan().to_string(),
};
}