use clap::ValueEnum; #[derive(Debug, Default)] pub struct Logger { pub level: LogLevel, } macro_rules! define_log_function { ($name:ident, $level:ident) => { pub fn $name(&self, message: S) where S: ToString { self.log(LogLevel::$level, message.to_string()); } }; } impl Logger { pub fn log(&self, level: LogLevel, message: S) where S: ToString { if level >= self.level { println!("{}", message.to_string()); } } define_log_function!(info, Info); define_log_function!(debug, Debug); define_log_function!(error, Error); } #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default, ValueEnum)] pub enum LogLevel { Debug, #[default] Info, Error, } #[macro_export] macro_rules! log { ($logger:expr, $level:ident, $($args:tt)*) => { $logger.$level(format!($($args)*)); }; ($logger:expr, $($args:tt)*) => { log!($logger, info, $($args)*); //TODO better use default level with log function instead of assuming info as default } } #[cfg(test)] mod test { use crate::logger::Logger; #[test] #[ignore] fn syntax_test() { let logger = Logger::default(); log!(logger, "Foo {}", "bar"); } }