diff --git a/src/main.rs b/src/main.rs index 9ab9bafa12c255eb5516edd5ddf38f03c5c224d3..4b7e95a83d82f7000e4ab7c47615483747d6f03e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,6 +114,35 @@ fn picolib_setup(args: &args::Run) { .propose_and_wait(traft::OpReturnOne, Duration::from_secs_f64(timeout)) }), ); + luamod.set("log", &[()]); + #[rustfmt::skip] + l.exec_with( + "picolib.log.highlight_key = ...", + tlua::function2(|key: String, color: Option<String>| -> Result<(), String> { + let color = match color.as_deref() { + None => None, + Some("red") => Some(tlog::Color::Red), + Some("green") => Some(tlog::Color::Green), + Some("blue") => Some(tlog::Color::Blue), + Some("cyan") => Some(tlog::Color::Cyan), + Some("yellow") => Some(tlog::Color::Yellow), + Some("magenta") => Some(tlog::Color::Magenta), + Some("white") => Some(tlog::Color::White), + Some("black") => Some(tlog::Color::Black), + Some(other) => { + return Err(format!("unknown color: {other:?}")) + } + }; + tlog::highlight_key(key, color); + Ok(()) + }), + ) + .unwrap(); + l.exec_with( + "picolib.log.clear_highlight = ...", + tlua::function0(tlog::clear_highlight), + ) + .unwrap(); { l.exec( r#" diff --git a/src/tlog.rs b/src/tlog.rs index c7b3911896cf2d2b8bb14776c43365d0574fc02a..4f78cb7204b6b28ee62a1fcd751c1c0e945548fb 100644 --- a/src/tlog.rs +++ b/src/tlog.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + pub struct Drain; pub fn root() -> slog::Logger { @@ -54,10 +56,49 @@ struct StrSerializer { pub str: String, } +#[rustfmt::skip] +#[repr(u8)] +#[derive(Clone, Copy)] +pub enum Color { + Red = 1, + Green = 2, + Blue = 4, + Cyan = 6, + Yellow = 3, + Magenta = 5, + White = 7, + Black = 0, +} + +pub static mut HIGHLIGHT: Option<HashMap<String, Color>> = None; + +#[inline] +pub fn clear_highlight() { + unsafe { + HIGHLIGHT = None; + } +} + +#[inline] +pub fn highlight_key(key: impl Into<String> + AsRef<str>, color: Option<Color>) { + let hi = unsafe { HIGHLIGHT.get_or_insert_with(HashMap::new) }; + if let Some(color) = color { + hi.insert(key.into(), color); + } else { + hi.remove(key.as_ref()); + } +} + impl slog::Serializer for StrSerializer { fn emit_arguments(&mut self, key: slog::Key, val: &std::fmt::Arguments) -> slog::Result { use std::fmt::Write; - write!(&mut self.str, ", {key}: {val}").unwrap(); + match unsafe { HIGHLIGHT.as_ref() }.and_then(|h| h.get(key)) { + Some(&color) => { + let color = color as u8; + write!(&mut self.str, ", \x1b[3{color}m{key}: {val}\x1b[0m").unwrap(); + } + _ => write!(&mut self.str, ", {key}: {val}").unwrap(), + } Ok(()) } }