From 7cb1316ff2a0e8196ba137e1fb4f5feb58a8ac59 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Wed, 6 Mar 2024 20:34:54 -0800 Subject: [PATCH] Deprecate and rename 'clear' to 'resetting'. Resolves #42. --- src/attr_quirk.rs | 19 +++++++++++++------ src/lib.rs | 27 +++++++++++++++------------ src/macros.rs | 27 ++++++++++++++++++++++----- src/paint.rs | 4 ++-- src/style.rs | 4 ++-- tests/basic.rs | 18 ++++++++++++++++++ 6 files changed, 72 insertions(+), 27 deletions(-) diff --git a/src/attr_quirk.rs b/src/attr_quirk.rs index 8a697b8..255e54e 100644 --- a/src/attr_quirk.rs +++ b/src/attr_quirk.rs @@ -104,20 +104,27 @@ pub enum Quirk { /// /// See the [crate level docs](crate#wrapping) for details. Wrap, - /// Linger: do not clear the style after it is applied. + /// Linger: do not reset the style after it is applied. /// /// Typically applied via the [`linger()`](crate::Painted::linger()) builder /// method. /// /// See the [crate level docs](crate#lingering) for details. Linger, - /// Always clear styling afterwards, even if no actual styling was applied. + /// **Deprecated:** Use [`Quirk::Resetting`] instead. + #[deprecated( + since = "1.0.1", + note = "renamed to `Resetting` due to builder method conflicts with `Vec::clear()`.\n\ + `Quirk::Clear` will be removed in a future release." + )] + Clear, + /// Always reset styling afterwards, even if no actual styling was applied. /// /// Overrides the [`Linger`](Quirk::Linger) quirk if present. /// - /// Typically applied via the [`clear()`](crate::Painted::clear()) builder - /// method. - Clear, + /// Typically applied via the [`resetting()`](crate::Painted::resetting()) + /// builder method. + Resetting, /// Brighten the foreground color if it is not already bright. /// /// Typically applied via the [`bright()`](crate::Painted::bright()) builder @@ -140,7 +147,7 @@ set_enum! { } set_enum! { - Quirk { Mask, Wrap, Linger, Clear, Bright, OnBright } + Quirk { Mask, Wrap, Linger, Clear, Resetting, Bright, OnBright } } impl Attribute { diff --git a/src/lib.rs b/src/lib.rs index 81edfb3..c5e66ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -208,15 +208,15 @@ //! //! Styling can _linger_ beyond a single value via [`Quirk::Linger`] or the //! equivalent [`linger()`](Painted::linger()) constructor. A lingering style -//! does not clear itself after being applied. In other words, the style lingers -//! on beyond the value it's applied to, until something else clears the +//! does not reset itself after being applied. In other words, the style lingers +//! on beyond the value it's applied to, until something else resets the //! respective styling. //! -//! The complement to lingering is force clearing via [`Quirk::Clear`] or the -//! equivalent [`clear()`](Painted::clear()) constructor. Force clearing, as the -//! name implies, forces a clear suffix to be emitted after the value, -//! irrespective of any lingering applied. It can be used as a way to finalize a -//! lingering style. +//! The complement to lingering is force resetting via [`Quirk::Resetting`] or +//! the equivalent [`resetting()`](Painted::resetting()) constructor. Force +//! resetting, as the name implies, forces a reset suffix to be emitted after +//! the value, irrespective of any lingering applied. It can be used as a way to +//! finalize a lingering style. //! //! Lingering itself is useful in situations where a given style is to be //! repeated across multiple values, or when style is intended to persist even @@ -230,7 +230,7 @@ //! println!("Hello! {} {} things with {} {}?", //! "How".magenta().underline().linger(), //! "are".italic().linger(), -//! "you".on_yellow(), // doesn't linger, so all styling is cleared here +//! "you".on_yellow(), // doesn't linger, so all styling is reset here //! "today".blue()); //! ``` //! @@ -245,9 +245,9 @@ //! //! println!("Hello! {} {} things with {} {}?", //! "How".magenta().underline().linger(), -//! "are".italic(), // doesn't linger, so all styling is cleared here +//! "are".italic(), // doesn't linger, so all styling is reset here //! "you".on_yellow().linger(), -//! "today".blue()); // doesn't linger; styling is cleared +//! "today".blue()); // doesn't linger; styling is reset //! ``` //! //! `>` Hello! @@ -265,8 +265,8 @@ //! println!("{} B {} {} {} F", //! "A".red().linger(), //! "C".underline().linger(), -//! "D", // doesn't linger, but no styling applied, thus no clear -//! "E".clear()); // explicitly clear +//! "D", // doesn't linger, but no styling applied, thus no reset +//! "E".resetting()); // explicitly reset //! ``` //! //! `>` A B C D E F @@ -344,6 +344,9 @@ #![cfg_attr(feature = "_nightly", feature(doc_cfg))] #![deny(missing_docs)] +// FIXME: Remove once `clear()` and `Quirk::Clear` are removed. +#![allow(useless_deprecated, deprecated)] + #[cfg(all(not(feature = "std"), feature = "alloc"))] extern crate alloc; diff --git a/src/macros.rs b/src/macros.rs index b02760d..8969caf 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -28,7 +28,10 @@ macro_rules! set_enum { } macro_rules! constructor { - ([$($q:tt)*] $r:ty, $R:ty, $p:ident, $prop:ident => $V:path $([$($a:ident : $T:ty),+])?) => { + ( + [$($q:tt)*] $r:ty, $R:ty, $p:ident, + $(#[$pattr:meta])* $prop:ident => $V:path $([$($a:ident : $T:ty),+])? + ) => { /// Returns `self` with the #[doc = concat!("[`", stringify!($p), "()`](Self::", stringify!($p), "())")] /// set to @@ -46,6 +49,7 @@ macro_rules! constructor { )] /// ``` #[inline] + $(#[$pattr])* $($q)* fn $prop(self: $r $($(,$a: $T)+)?) -> $R { let v = $V $(($($a),*))?; self.apply(crate::style::Application::$p(v)) @@ -62,7 +66,10 @@ macro_rules! constructor { } macro_rules! signature { - ([$($q:tt)*] $r:ty, $R:ty, $p:ident, $prop:ident => $V:path $([$($a:ident : $T:ty),+])?) => { + ( + [$($q:tt)*] $r:ty, $R:ty, $p:ident, + $(#[$pattr:meta])* $prop:ident => $V:path $([$($a:ident : $T:ty),+])? + ) => { /// Returns `self` with the #[doc = concat!("[`", stringify!($p), "()`](Self::", stringify!($p), "())")] /// set to @@ -79,6 +86,7 @@ macro_rules! signature { "println!(\"{}\", value.", stringify!($prop), "(", $(stringify!($($a),+),)? "));" )] /// ``` + $(#[$pattr])* $($q)* fn $prop(self: $r $($(,$a: $T)+)?) -> $R; }; @@ -90,14 +98,17 @@ macro_rules! signature { macro_rules! define_property { ([$d:tt] $(#[$attr:meta])* $kind:ident ($A:ty) { - $($prop:ident => $V:path $([$($a:tt)*])?),* $(,)? + $($(#[$pattr:meta])* $prop:ident => $V:path $([$($a:tt)*])?),* $(,)? }) => { macro_rules! $kind { ($d ([$d ($qual:tt)*])? $cont:ident ($r:ty) -> $R:ty) => ( $cont!([$d ($d ($qual)*)?] $(#[$attr])* $r, $R, $kind($A)); $( - $cont!([$d ($d ($qual)*)?] $r, $R, $kind, $prop => $V $([$($a)*] )?); + $cont!( + [$d ($d ($qual)*)?] + $r, $R, $kind, $(#[$pattr])* $prop => $V $([$($a)*] )? + ); )* ) } @@ -112,7 +123,7 @@ macro_rules! define_property { // Check that every variant of a property is covered. macro_rules! check_property_exhaustiveness { - ($A:ident $({ $( $p:ident => $V:path $([ $($a:tt)* ])?),* $(,)? })? ) => { + ($A:ident $({ $($(#[$pattr:meta])* $p:ident => $V:path $([ $($a:tt)* ])?),* $(,)? })? ) => { const _: () = {$( use crate::*; fn _check() { @@ -309,7 +320,13 @@ define_properties! { mask => Quirk::Mask, wrap => Quirk::Wrap, linger => Quirk::Linger, + #[deprecated( + since = "1.0.1", + note = "renamed to `resetting()` due to conflicts with `Vec::clear()`.\n\ + The `clear()` method will be removed in a future release." + )] clear => Quirk::Clear, + resetting => Quirk::Resetting, bright => Quirk::Bright, on_bright => Quirk::OnBright, }, diff --git a/src/paint.rs b/src/paint.rs index a608a15..492d381 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -177,7 +177,7 @@ impl Painted { } #[cfg(feature = "alloc")] - pub(crate) fn clear_fmt_args( + pub(crate) fn reset_fmt_args( &self, fmt: &dyn Fn(&T, &mut fmt::Formatter) -> fmt::Result, f: &mut fmt::Formatter, @@ -254,7 +254,7 @@ impl Painted { match (enabled, masked, self.style.quirks.contains(Quirk::Wrap)) { (true, _, true) => self.color_wrap_fmt_args(fmt, f, &_args), (true, _, false) => self.color_fmt_value(fmt, f), - (false, false, true) => self.clear_fmt_args(fmt, f, &_args), + (false, false, true) => self.reset_fmt_args(fmt, f, &_args), (false, false, false) => fmt(&self.value, f), (false, true, _) => Ok(()), } diff --git a/src/style.rs b/src/style.rs index dcb97c7..3048c9b 100644 --- a/src/style.rs +++ b/src/style.rs @@ -250,7 +250,7 @@ impl Style { /// } /// ``` pub fn fmt_suffix(&self, f: &mut dyn fmt::Write) -> fmt::Result { - if !self.quirks.contains(Quirk::Clear) { + if !self.quirks.contains(Quirk::Resetting) && !self.quirks.contains(Quirk::Clear) { if self.quirks.contains(Quirk::Linger) || self == &Style::DEFAULT { return Ok(()); } @@ -266,7 +266,7 @@ impl Style { #[cfg(feature = "alloc")] #[cfg_attr(feature = "_nightly", doc(cfg(feature = "alloc")))] pub fn suffix(&self) -> Cow<'static, str> { - if !self.quirks.contains(Quirk::Clear) { + if !self.quirks.contains(Quirk::Resetting) && !self.quirks.contains(Quirk::Clear) { if self.quirks.contains(Quirk::Linger) || self == &Style::DEFAULT { return Cow::from(""); } diff --git a/tests/basic.rs b/tests/basic.rs index e49d7e5..a2d081a 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -196,6 +196,24 @@ fn lingering() { \u{1b}[34mtoday\u{1b}[0m?" }; + assert_eq! { + format!("{} B {} {} {} F", + "A".red().linger(), + "C".underline().linger(), + "D", // doesn't linger, but no styling applied, thus no reset + "E".resetting()), // explicitly reset + "\u{1b}[31mA B \u{1b}[4mC D E\u{1b}[0m F" + }; + + assert_eq! { + format!("{} B {} {} {} F", + "A".red().linger(), + "C".underline().linger(), + "D", // doesn't linger, but no styling applied, thus no reset + "E".clear()), // explicitly reset + "\u{1b}[31mA B \u{1b}[4mC D E\u{1b}[0m F" + }; + yansi::whenever(Condition::DEFAULT); }