From 817bb7bffd8d98abc5328b9a503010f264562c1d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 10 Sep 2022 16:12:24 +0200 Subject: [PATCH 1/5] cargo fmt --- src/lib.rs | 14 +++++++++----- tests/debug.rs | 4 ++-- tests/error.rs | 4 ++-- tests/info.rs | 4 ++-- tests/logger/mod.rs | 11 +++++++---- tests/trace.rs | 4 ++-- tests/warn.rs | 4 ++-- 7 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fc94e41..821c360 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,17 +56,19 @@ use std::sync::{Mutex, MutexGuard, PoisonError}; #[doc(hidden)] pub struct __MessagesSet { - inner: Mutex> + inner: Mutex>, } impl __MessagesSet { pub fn new() -> __MessagesSet { __MessagesSet { - inner: Mutex::new(BTreeSet::new()) + inner: Mutex::new(BTreeSet::new()), } } - pub fn lock(&self) -> Result>, PoisonError>>> { + pub fn lock( + &self, + ) -> Result>, PoisonError>>> { self.inner.lock() } } @@ -214,13 +216,15 @@ macro_rules! trace_once { #[cfg(test)] mod tests { + use log::{LevelFilter, Log, Metadata, Record}; use std::cell::Cell; use std::sync::Once; - use log::{Log, Record, Metadata, LevelFilter}; struct SimpleLogger; impl Log for SimpleLogger { - fn enabled(&self, _: &Metadata) -> bool {true} + fn enabled(&self, _: &Metadata) -> bool { + true + } fn log(&self, _: &Record) {} fn flush(&self) {} } diff --git a/tests/debug.rs b/tests/debug.rs index 820ad6c..27887fa 100644 --- a/tests/debug.rs +++ b/tests/debug.rs @@ -21,8 +21,8 @@ fn debug() { } let data = logger::logged_data(); - let expected = -"Here 42! + let expected = "\ +Here 42! Here 42! Here 42! Here 42! diff --git a/tests/error.rs b/tests/error.rs index 1b22547..2dc3523 100644 --- a/tests/error.rs +++ b/tests/error.rs @@ -21,8 +21,8 @@ fn error() { } let data = logger::logged_data(); - let expected = -"Here 42! + let expected = "\ +Here 42! Here 42! Here 42! Here 42! diff --git a/tests/info.rs b/tests/info.rs index 8f41b3d..7196811 100644 --- a/tests/info.rs +++ b/tests/info.rs @@ -21,8 +21,8 @@ fn info() { } let data = logger::logged_data(); - let expected = -"Here 42! + let expected = "\ +Here 42! Here 42! Here 42! Here 42! diff --git a/tests/logger/mod.rs b/tests/logger/mod.rs index 4cdda43..33d21f5 100644 --- a/tests/logger/mod.rs +++ b/tests/logger/mod.rs @@ -1,8 +1,8 @@ -use log::{Record, LevelFilter, Metadata}; -use std::sync::{Mutex, Once}; +use log::{LevelFilter, Metadata, Record}; use std::fmt::Write; +use std::sync::{Mutex, Once}; -lazy_static::lazy_static!{ +lazy_static::lazy_static! { static ref LOGGED_DATA: Mutex = Mutex::new(String::new()); } @@ -33,5 +33,8 @@ pub fn init() { } pub fn logged_data() -> String { - LOGGED_DATA.lock().expect("Mutex has been poisonned").clone() + LOGGED_DATA + .lock() + .expect("Mutex has been poisonned") + .clone() } diff --git a/tests/trace.rs b/tests/trace.rs index c3b43e1..1c54dcd 100644 --- a/tests/trace.rs +++ b/tests/trace.rs @@ -21,8 +21,8 @@ fn trace() { } let data = logger::logged_data(); - let expected = -"Here 42! + let expected = "\ +Here 42! Here 42! Here 42! Here 42! diff --git a/tests/warn.rs b/tests/warn.rs index 11b6aba..fa97309 100644 --- a/tests/warn.rs +++ b/tests/warn.rs @@ -21,8 +21,8 @@ fn warn() { } let data = logger::logged_data(); - let expected = -"Here 42! + let expected = "\ +Here 42! Here 42! Here 42! Here 42! From 538a67a06f6a0e008977b905ea73e76a30798d88 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 10 Sep 2022 16:13:39 +0200 Subject: [PATCH 2/5] Add support for captured identifiers in format strings --- README.md | 6 ++-- src/lib.rs | 20 +++++------- tests/captured-identifiers-format-strings.rs | 33 ++++++++++++++++++++ 3 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 tests/captured-identifiers-format-strings.rs diff --git a/README.md b/README.md index d456111..327fe82 100644 --- a/README.md +++ b/README.md @@ -41,19 +41,19 @@ use log_once::{info_once, warn_once}; pub fn shave_the_yak(yaks: &[Yak]) { for yak in yaks { - info!(target: "yak_events", "Commencing yak shaving for {:?}", yak); + info!(target: "yak_events", "Commencing yak shaving for {yak:?}"); loop { match find_a_razor() { Ok(razor) => { // This will only appear once in the logger output for each razor - info_once!("Razor located: {}", razor); + info_once!("Razor located: {razor}"); yak.shave(razor); break; } Err(err) => { // This will only appear once in the logger output for each error - warn_once!("Unable to locate a razor: {}, retrying", err); + warn_once!("Unable to locate a razor: {err}, retrying"); } } } diff --git a/src/lib.rs b/src/lib.rs index 821c360..36b46ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,19 +26,19 @@ //! # fn find_a_razor() -> Result { Ok(1) } //! pub fn shave_the_yak(yaks: &[Yak]) { //! for yak in yaks { -//! info!(target: "yak_events", "Commencing yak shaving for {:?}", yak); +//! info!(target: "yak_events", "Commencing yak shaving for {yak:?}"); //! //! loop { //! match find_a_razor() { //! Ok(razor) => { //! // This will only appear once in the logger output for each razor -//! info_once!("Razor located: {}", razor); +//! info_once!("Razor located: {razor}"); //! yak.shave(razor); //! break; //! } //! Err(err) => { //! // This will only appear once in the logger output for each error -//! warn_once!("Unable to locate a razor: {}, retrying", err); +//! warn_once!("Unable to locate a razor: {err}, retrying"); //! } //! } //! } @@ -96,21 +96,17 @@ macro_rules! log_once { &(*__SEEN_MESSAGES) } }); - (target: $target:expr, $lvl:expr, $message:expr) => ({ + (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({ + let message = format!($($arg)+); #[allow(non_snake_case)] let __SEEN_MESSAGES = $crate::log_once!(@CREATE STATIC); let mut seen_messages = __SEEN_MESSAGES.lock().expect("Mutex was poisonned"); - let event = String::from(stringify!($target)) + stringify!($lvl) + $message.as_ref(); + let event = String::from(stringify!($target)) + stringify!($lvl) + message.as_ref(); if seen_messages.insert(event) { - log::log!(target: $target, $lvl, "{}", $message); + log::log!(target: $target, $lvl, "{}", message); } }); - (target: $target:expr, $lvl:expr, $format:expr, $($arg:tt)+) => ({ - let message = format!($format, $($arg)+); - $crate::log_once!(target: $target, $lvl, message); - }); - ($lvl:expr, $message:expr) => ($crate::log_once!(target: module_path!(), $lvl, $message)); - ($lvl:expr, $format:expr, $($arg:tt)+) => ($crate::log_once!(target: module_path!(), $lvl, $format, $($arg)+)); + ($lvl:expr, $($arg:tt)+) => ($crate::log_once!(target: module_path!(), $lvl, $($arg)+)); } /// Logs a message once at the error level. diff --git a/tests/captured-identifiers-format-strings.rs b/tests/captured-identifiers-format-strings.rs new file mode 100644 index 0000000..b7c6ed0 --- /dev/null +++ b/tests/captured-identifiers-format-strings.rs @@ -0,0 +1,33 @@ +//! Test that we can support capture identifiers in format strings introduced in Rust 1.58.0. +//! See https://blog.rust-lang.org/2022/01/13/Rust-1.58.0.html#captured-identifiers-in-format-strings + +mod logger; + +#[test] +fn info() { + logger::init(); + + let value = "FOO"; + + for _ in 0..2 { + log::info!("This is logged twice {value}!"); + } + + for _ in 0..2 { + log_once::info_once!("This is only logged once {value}!"); + } + + for i in 0..2 { + log_once::info_once!("This will be logged twice {i}!"); + } + + let data = logger::logged_data(); + let expected = "\ +This is logged twice FOO! +This is logged twice FOO! +This is only logged once FOO! +This will be logged twice 0! +This will be logged twice 1! +"; + assert_eq!(data, expected); +} From 49247dbed838bdaacabc170885610a5c43693d35 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 10 Sep 2022 16:19:15 +0200 Subject: [PATCH 3/5] Document log_once macro branches --- src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 36b46ed..1420540 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,6 +96,8 @@ macro_rules! log_once { &(*__SEEN_MESSAGES) } }); + + // log_once!(target: "my_target", Level::Info, "Some {}", "logging") (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({ let message = format!($($arg)+); #[allow(non_snake_case)] @@ -106,6 +108,8 @@ macro_rules! log_once { log::log!(target: $target, $lvl, "{}", message); } }); + + // log_once!(Level::Info, "Some {}", "logging") ($lvl:expr, $($arg:tt)+) => ($crate::log_once!(target: module_path!(), $lvl, $($arg)+)); } From 3caaf250dcaecf1b1c95f258a75b7c79d40938a7 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 10 Sep 2022 16:24:42 +0200 Subject: [PATCH 4/5] Don't force users to also depend on `log` crate --- src/lib.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1420540..b246fc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,11 @@ //! # fn main() {} //! ``` -extern crate log; +// We re-export the log crate so that the log_once macros can use it directly. +// That way users don't need to depend on `log` explicitly. +// This is especially nice for people who use `tracing` for logging, but still use `log_once`. +pub use log; + pub use log::Level; use std::collections::BTreeSet; @@ -105,7 +109,7 @@ macro_rules! log_once { let mut seen_messages = __SEEN_MESSAGES.lock().expect("Mutex was poisonned"); let event = String::from(stringify!($target)) + stringify!($lvl) + message.as_ref(); if seen_messages.insert(event) { - log::log!(target: $target, $lvl, "{}", message); + $crate::log::log!(target: $target, $lvl, "{}", message); } }); @@ -235,8 +239,8 @@ mod tests { fn called_once() { static START: Once = Once::new(); START.call_once(|| { - ::log::set_logger(&LOGGER).expect("Could not set the logger"); - ::log::set_max_level(LevelFilter::Trace); + log::set_logger(&LOGGER).expect("Could not set the logger"); + log::set_max_level(LevelFilter::Trace); }); let counter = Cell::new(0); From 73c56ce9b059118cb549fb5eeaad708ec5cdc503 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 10 Sep 2022 16:26:04 +0200 Subject: [PATCH 5/5] Clippy fixes --- src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b246fc5..5e82f70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,12 +64,15 @@ pub struct __MessagesSet { } impl __MessagesSet { - pub fn new() -> __MessagesSet { - __MessagesSet { + #[must_use] + pub fn new() -> Self { + Self { inner: Mutex::new(BTreeSet::new()), } } + /// # Errors + /// Mutex poisoning. pub fn lock( &self, ) -> Result>, PoisonError>>> {