1use colored::*;
2
3pub enum LogLevel {
4 Info,
5 Warn,
6 Error,
7}
8
9pub struct Diagnostic {
10 level: LogLevel,
11 message: String,
12 context: Option<String>,
13}
14
15impl Diagnostic {
16 pub fn new(level: LogLevel, message: &str, context: Option<&str>) -> Self {
18 Self {
19 level,
20 message: message.to_string(),
21 context: context.map(|s| s.to_string()),
22 }
23 }
24
25 pub fn emit(&self) {
27 match self.level {
28 LogLevel::Info => println!("[{}]: {}", String::from("INFO").blue(), self.message),
29 LogLevel::Warn => println!("[{}]: {}", String::from("WARNING").yellow(), self.message),
30 LogLevel::Error => {
31 eprintln!("[{}]: {}", String::from("ERROR").red(), self.message);
32 if let Some(ref context) = self.context {
33 eprintln!("{}: {}", "Context".bold(), context);
34 }
35 }
36 }
37 }
38}
39
40#[macro_export]
42macro_rules! log_info {
43 ($($arg:tt)*) => {
44 $crate::Diagnostic::new($crate::LogLevel::Info, &format!($($arg)*), None).emit();
45 };
46}
47
48#[macro_export]
50macro_rules! log_warn {
51 ($($arg:tt)*) => {
52 $crate::Diagnostic::new($crate::LogLevel::Warning, &format!($($arg)*), None).emit();
53 };
54}
55
56#[macro_export]
58macro_rules! log_error {
59 ($($arg:tt)*) => {
60 $crate::Diagnostic::new($crate::LogLevel::Error, &format!($($arg)*), None).emit();
61 };
62}