use anstyle::Style;
use paste::paste;
macro_rules! colour {
($flavour:ident, $colour:ident) => {{
let catppuccin::Rgb { r, g, b } = catppuccin::PALETTE.$flavour.colors.$colour.rgb;
anstyle::Color::Rgb(anstyle::RgbColor(r, g, b))
}};
}
macro_rules! meowg {
($($flavour:ident)+) => {
paste! {
$(
#[doc = "Logger based on the Catppuccin " $flavour:camel " flavour."]
pub struct [<$flavour:camel>];
impl [<$flavour:camel>] {
const ERROR: Style = Style::new().fg_color(Some(colour!($flavour, red))).bold();
const WARN: Style = Style::new().fg_color(Some(colour!($flavour, yellow))).italic();
const INFO: Style = Style::new().fg_color(Some(colour!($flavour, text)));
const DEBUG: Style = Style::new().fg_color(Some(colour!($flavour, subtext0)));
const TRACE: Style = Style::new().fg_color(Some(colour!($flavour, overlay1)));
pub fn install() -> Result<(), log::SetLoggerError> {
use log::LevelFilter;
log::set_max_level(if cfg!(debug_assertions) { LevelFilter::Trace } else { LevelFilter::Info });
log::set_logger(&Self)
}
}
impl log::Log for [<$flavour:camel>] {
fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool {
true
}
#[doc = "Log a " $flavour:camel "‐coloured message to standard error."]
fn log(&self, record: &log::Record<'_>) {
use log::Level;
let style = match record.level() {
Level::Error => Self::ERROR,
Level::Warn => Self::WARN,
Level::Info => Self::INFO,
Level::Debug => Self::DEBUG,
Level::Trace => Self::TRACE,
};
anstream::eprintln!("{style}{}{style:#}", record.args());
}
fn flush(&self) {
use std::io::Write;
let _ = anstream::stderr().flush();
}
}
)+
}
};
}
meowg!(latte frappe macchiato mocha);
#[cfg(test)]
mod tests {
use super::*;
use log::{debug, error, info, trace, warn};
#[test]
fn log() {
Mocha::install().unwrap();
error!("error");
warn!("warn");
info!("info");
debug!("debug");
trace!("trace");
}
}