use clap::Args;
use crossterm::style::{Color, Stylize};
use std::fmt::Write;
const LOG_GUIDE: &str = include_str!("../LOG_GUIDE.md");
#[derive(Args)]
pub struct LogArgs {
#[arg(value_parser = parse_level)]
pub level: LogLevel,
pub message: Vec<String>,
#[arg(long)]
pub guide: bool,
}
#[derive(Clone)]
pub enum LogLevel {
Info,
Warn,
Error,
Debug,
}
fn parse_level(s: &str) -> Result<LogLevel, String> {
match s.to_lowercase().as_str() {
"info" => Ok(LogLevel::Info),
"warn" | "warning" => Ok(LogLevel::Warn),
"error" => Ok(LogLevel::Error),
"debug" => Ok(LogLevel::Debug),
_ => Err(format!("nivel inválido: {s}. Usa: info, warn, error, debug")),
}
}
fn level_label(level: &LogLevel) -> &'static str {
match level {
LogLevel::Info => "INFO",
LogLevel::Warn => "WARN",
LogLevel::Error => "ERROR",
LogLevel::Debug => "DEBUG",
}
}
fn level_color(level: &LogLevel) -> Color {
match level {
LogLevel::Info => Color::Cyan,
LogLevel::Warn => Color::Yellow,
LogLevel::Error => Color::Red,
LogLevel::Debug => Color::Rgb { r: 120, g: 120, b: 120 },
}
}
pub fn run(args: LogArgs) {
if args.guide {
println!("{}", LOG_GUIDE);
return;
}
let message = args.message.join(" ");
let mut buf = String::new();
let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S");
write!(buf, "{}", now.to_string().with(Color::Rgb { r: 120, g: 120, b: 120 })).unwrap();
write!(buf, " ").unwrap();
write!(buf, "{:5}", level_label(&args.level).with(level_color(&args.level))).unwrap();
write!(buf, " ").unwrap();
write!(buf, "{}", message.with(Color::White)).unwrap();
println!("{}", buf);
}