Skip to content

Commit

Permalink
Merge pull request #165 from joshtriplett/anstyle-render-helper
Browse files Browse the repository at this point in the history
RFC: Style code/reset rendering via Display
  • Loading branch information
epage authored Jan 29, 2024
2 parents 82539b6 + da0569e commit ea42606
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 21 deletions.
10 changes: 4 additions & 6 deletions crates/anstyle/src/reset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ pub struct Reset;

impl Reset {
/// Render the ANSI code
///
/// `Reset` also implements `Display` directly, so calling this method is optional.
#[inline]
pub fn render(self) -> impl core::fmt::Display + Copy + Clone {
ResetDisplay
self
}
}

#[derive(Copy, Clone, Default, Debug)]
struct ResetDisplay;

impl core::fmt::Display for ResetDisplay {
impl core::fmt::Display for Reset {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
RESET.fmt(f)
}
Expand All @@ -25,5 +24,4 @@ pub(crate) const RESET: &str = "\x1B[0m";
fn print_size_of() {
use std::mem::size_of;
dbg!(size_of::<Reset>());
dbg!(size_of::<ResetDisplay>());
}
56 changes: 41 additions & 15 deletions crates/anstyle/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ use crate::reset::RESET;

/// ANSI Text styling
///
/// You can print a `Style` to render the corresponding ANSI code.
/// Using the alternate flag `#` will render the ANSI reset code, if needed.
/// Together, this makes it convenient to render styles using inline format arguments.
///
/// # Examples
///
/// ```rust
/// let style = anstyle::Style::new().bold();
///
/// let value = 42;
/// println!("{style}{value}{style:#}");
/// ```
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Style {
Expand Down Expand Up @@ -91,11 +98,33 @@ impl Style {
}

/// Render the ANSI code
///
/// `Style` also implements `Display` directly, so calling this method is optional.
#[inline]
pub fn render(self) -> impl core::fmt::Display + Copy + Clone {
StyleDisplay(self)
}

fn fmt_to(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Display as _;

self.effects.render().fmt(f)?;

if let Some(fg) = self.fg {
fg.render_fg().fmt(f)?;
}

if let Some(bg) = self.bg {
bg.render_bg().fmt(f)?;
}

if let Some(underline) = self.underline {
underline.render_underline().fmt(f)?;
}

Ok(())
}

/// Write the ANSI code
#[inline]
#[cfg(feature = "std")]
Expand Down Expand Up @@ -374,26 +403,23 @@ impl core::cmp::PartialEq<crate::Effects> for Style {
}
}

impl core::fmt::Display for Style {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
self.render_reset().fmt(f)
} else {
self.fmt_to(f)
}
}
}

#[derive(Copy, Clone, Default, Debug)]
struct StyleDisplay(Style);

impl core::fmt::Display for StyleDisplay {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.effects.render().fmt(f)?;

if let Some(fg) = self.0.fg {
fg.render_fg().fmt(f)?;
}

if let Some(bg) = self.0.bg {
bg.render_bg().fmt(f)?;
}

if let Some(underline) = self.0.underline {
underline.render_underline().fmt(f)?;
}

Ok(())
self.0.fmt_to(f)
}
}

Expand Down

0 comments on commit ea42606

Please sign in to comment.