From 1cb523b87d3dc113ecc33fdf6cbee8ae63fbfec2 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 14 Apr 2023 21:38:48 +0200 Subject: [PATCH] subscriber: add ability to disable ANSI without crate feature (#2532) ## Motivation Currently it is not possible to disable ANSI in `fmt::Subscriber` without enabling the "ansi" crate feature. This makes it difficult for users to implement interoperable settings that are controllable with crate features without having to pull in the dependencies "ansi" does. I hit this while writing an application with multiple logging options set during compile-time and I wanted to cut down on dependencies if possible. ## Solution This changes `fmt::Subscriber::with_ansi()` to not require the "ansi" feature flag. This way, `with_ansi(false)` can be called even when the "ansi" feature is disabled. Calling `with_ansi(true)` when the "ansi" feature is not enabled will panic in debug mode, or print a warning if debug assertions are disabled. Co-authored-by: Eliza Weisman --- tracing-subscriber/src/fmt/fmt_subscriber.rs | 28 +++++++++++++++++--- tracing-subscriber/src/fmt/mod.rs | 18 ++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/tracing-subscriber/src/fmt/fmt_subscriber.rs b/tracing-subscriber/src/fmt/fmt_subscriber.rs index 9887b711ff..1b89039261 100644 --- a/tracing-subscriber/src/fmt/fmt_subscriber.rs +++ b/tracing-subscriber/src/fmt/fmt_subscriber.rs @@ -274,10 +274,32 @@ impl Subscriber { } } - /// Enable ANSI terminal colors for formatted output. - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] + /// Sets whether or not the formatter emits ANSI terminal escape codes + /// for colors and other text formatting. + /// + /// Enabling ANSI escapes (calling `with_ansi(true)`) requires the "ansi" + /// crate feature flag. Calling `with_ansi(true)` without the "ansi" + /// feature flag enabled will panic if debug assertions are enabled, or + /// print a warning otherwise. + /// + /// This method itself is still available without the feature flag. This + /// is to allow ANSI escape codes to be explicitly *disabled* without + /// having to opt-in to the dependencies required to emit ANSI formatting. + /// This way, code which constructs a formatter that should never emit + /// ANSI escape codes can ensure that they are not used, regardless of + /// whether or not other crates in the dependency graph enable the "ansi" + /// feature flag. pub fn with_ansi(self, ansi: bool) -> Self { + #[cfg(not(feature = "ansi"))] + if ansi { + const ERROR: &str = + "tracing-subscriber: the `ansi` crate feature is required to enable ANSI terminal colors"; + #[cfg(debug_assertions)] + panic!("{}", ERROR); + #[cfg(not(debug_assertions))] + eprintln!("{}", ERROR); + } + Subscriber { is_ansi: ansi, ..self diff --git a/tracing-subscriber/src/fmt/mod.rs b/tracing-subscriber/src/fmt/mod.rs index ba5066d2ec..38acf4d092 100644 --- a/tracing-subscriber/src/fmt/mod.rs +++ b/tracing-subscriber/src/fmt/mod.rs @@ -610,9 +610,21 @@ where } } - /// Enable ANSI terminal colors for formatted output. - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] + /// Sets whether or not the formatter emits ANSI terminal escape codes + /// for colors and other text formatting. + /// + /// Enabling ANSI escapes (calling `with_ansi(true)`) requires the "ansi" + /// crate feature flag. Calling `with_ansi(true)` without the "ansi" + /// feature flag enabled will panic if debug assertions are enabled, or + /// print a warning otherwise. + /// + /// This method itself is still available without the feature flag. This + /// is to allow ANSI escape codes to be explicitly *disabled* without + /// having to opt-in to the dependencies required to emit ANSI formatting. + /// This way, code which constructs a formatter that should never emit + /// ANSI escape codes can ensure that they are not used, regardless of + /// whether or not other crates in the dependency graph enable the "ansi" + /// feature flag. pub fn with_ansi(self, ansi: bool) -> CollectorBuilder, F, W> { CollectorBuilder { inner: self.inner.with_ansi(ansi),