diff --git a/spdlog/src/log_macros.rs b/spdlog/src/log_macros.rs index 547849ac..234f0813 100644 --- a/spdlog/src/log_macros.rs +++ b/spdlog/src/log_macros.rs @@ -235,14 +235,38 @@ macro_rules! trace { #[macro_export] macro_rules! __kv { ({}) => (&[]); - ({ $( $k:ident = $v:expr ),+ $(,)? }) => { - &[$(($crate::kv::Key::__from_static_str(stringify!($k)), $v.into())),+] + ({ $($ttm:tt)+ }) => { + $crate::__kv!(@{} $($ttm)+) + }; + + (@{$($done:tt)*} $k:ident = $v:expr $(,$($rest:tt)*)?) => ($crate::__kv!(@{$($done)* $k [ ] = $v,} $($($rest)*)?)); + (@{$($done:tt)*} $k:ident : = $v:expr $(,$($rest:tt)*)?) => ($crate::__kv!(@{$($done)* $k [: ] = $v,} $($($rest)*)?)); + (@{$($done:tt)*} $k:ident :? = $v:expr $(,$($rest:tt)*)?) => ($crate::__kv!(@{$($done)* $k [:?] = $v,} $($($rest)*)?)); + (@{$( $k:ident [$($modifier:tt)*] = $v:expr ),+ $(,)?}) => { + &[$(($crate::kv::Key::__from_static_str(stringify!($k)), $crate::__kv_value!($($modifier)* = $v))),+] + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __kv_value { + (= $v:expr) => { + $crate::kv::Value::from(&$v) + }; + (: = $v:expr) => { + $crate::kv::Value::from_display(&$v) + }; + (:? = $v:expr) => { + $crate::kv::Value::from_debug(&$v) }; } #[cfg(test)] mod tests { - use std::sync::Arc; + use std::{ + fmt::{self, Debug, Display}, + sync::Arc, + }; use crate::{kv::KeyInner, prelude::*, test_utils::*}; @@ -253,18 +277,31 @@ mod tests { b.sink(test_sink.clone()).level_filter(LevelFilter::All) })); + struct Mods; + impl Debug for Mods { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "debug") + } + } + impl Display for Mods { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "display") + } + } + let mut check = vec![ (vec![], Level::Info, "logger".to_string()), (vec![], Level::Error, "logger, kv(0)".to_string()), ( - vec![(KeyInner::StaticStr("k1"), 114)], + vec![(KeyInner::StaticStr("kn"), "114514".to_string())], Level::Warn, "logger, kv(1)".to_string(), ), ( vec![ - (KeyInner::StaticStr("k1"), 114), - (KeyInner::StaticStr("k2"), 514), + (KeyInner::StaticStr("kn"), "114514".to_string()), + (KeyInner::StaticStr("kdi"), "display".to_string()), + (KeyInner::StaticStr("kde"), "debug".to_string()), ], Level::Critical, "logger, kv(2)".to_string(), @@ -273,8 +310,8 @@ mod tests { log!(logger: test, Level::Info, "logger"); log!(logger: test, kv: {}, Level::Error, "logger, kv(0)"); - log!(logger: test, kv: { k1 = 114 }, Level::Warn, "logger, kv(1)"); - log!(logger: test, kv: { k1 = 114, k2 = 514 }, Level::Critical, "logger, kv(2)"); + log!(logger: test, kv: { kn = 114514 }, Level::Warn, "logger, kv(1)"); + log!(logger: test, kv: { kn = 114514, kdi: = Mods, kde:? = Mods }, Level::Critical, "logger, kv(2)"); macro_rules! add_records { ( $($level:ident => $variant:ident),+ ) => { @@ -285,21 +322,22 @@ mod tests { $level!(logger: test, kv: {}, "{}: logger, kv(0)", stringify!($level)); check.push((vec![], Level::$variant, format!("{}: logger, kv(0)", stringify!($level)))); - $level!(logger: test, kv: { k1 = 114 }, "{}: logger, kv(1)", stringify!($level)); + $level!(logger: test, kv: { kn = 114514 }, "{}: logger, kv(1)", stringify!($level)); check.push(( - vec![(KeyInner::StaticStr("k1"), 114)], + vec![(KeyInner::StaticStr("kn"), "114514".to_string())], Level::$variant, format!("{}: logger, kv(1)", stringify!($level)) )); - $level!(logger: test, kv: { k1 = 114, k2 = 514 }, "{}: logger, kv(2)", stringify!($level)); + $level!(logger: test, kv: { kn = 114514, kdi: = Mods, kde:? = Mods }, "{}: logger, kv(s,mod)", stringify!($level)); check.push(( vec![ - (KeyInner::StaticStr("k1"), 114), - (KeyInner::StaticStr("k2"), 514) + (KeyInner::StaticStr("kn"), "114514".to_string()), + (KeyInner::StaticStr("kdi"), "display".to_string()), + (KeyInner::StaticStr("kde"), "debug".to_string()), ], Level::$variant, - format!("{}: logger, kv(2)", stringify!($level)) + format!("{}: logger, kv(s,mod)", stringify!($level)) )); )+ }; @@ -320,7 +358,7 @@ mod tests { ( record .key_values() - .map(|(k, v)| (k.inner(), v.to_i64().unwrap())) + .map(|(k, v)| (k.inner(), v.to_string())) .collect::>(), record.level(), record.payload().to_string(),