diff --git a/src/utils.rs b/src/utils.rs index c3d13504..9b661055 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -131,11 +131,8 @@ pub enum Attribute { StrikeThrough = 8, } -#[derive(Clone, Copy, PartialEq, Eq)] -struct Attributes(u16); - -impl Attributes { - const ATTRIBUTES_LOOKUP: [Attribute; 9] = [ +impl Attribute { + const MAP: [Attribute; 9] = [ Attribute::Bold, Attribute::Dim, Attribute::Italic, @@ -146,10 +143,15 @@ impl Attributes { Attribute::Hidden, Attribute::StrikeThrough, ]; +} +#[derive(Clone, Copy, PartialEq, Eq)] +struct Attributes(u16); + +impl Attributes { #[inline] const fn new() -> Self { - Attributes(0) + Self(0) } #[inline] @@ -166,14 +168,22 @@ impl Attributes { } #[inline] - fn ansi_nums(self) -> impl Iterator { - // Per construction of the enum - self.bits().map(|bit| bit + 1) + fn attrs(self) -> impl Iterator { + self.bits().map(|bit| Attribute::MAP[bit as usize]) } #[inline] - fn attrs(self) -> impl Iterator { - self.bits().map(|bit| Self::ATTRIBUTES_LOOKUP[bit as usize]) + fn is_empty(self) -> bool { + self.0 == 0 + } +} + +impl fmt::Display for Attributes { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for ansi in self.bits().map(|bit| bit + 1) { + write!(f, "\x1b[{ansi}m")?; + } + Ok(()) } } @@ -703,8 +713,8 @@ macro_rules! impl_fmt { } reset = true; } - for ansi_num in self.style.attrs.ansi_nums() { - write!(f, "\x1b[{}m", ansi_num)?; + if !self.style.attrs.is_empty() { + write!(f, "{}", self.style.attrs)?; reset = true; } } @@ -1021,10 +1031,9 @@ fn test_pad_str_with() { #[test] fn test_attributes_single() { - for attr in Attributes::ATTRIBUTES_LOOKUP { + for attr in Attribute::MAP { let attrs = Attributes::new().insert(attr); assert_eq!(attrs.bits().collect::>(), [attr as u16]); - assert_eq!(attrs.ansi_nums().collect::>(), [attr as u16 + 1]); assert_eq!(attrs.attrs().collect::>(), [attr]); assert_eq!(format!("{:?}", attrs), format!("{{{:?}}}", attr)); } @@ -1046,7 +1055,7 @@ fn test_attributes_many() { Attribute::Reverse, Attribute::StrikeThrough, ], - &Attributes::ATTRIBUTES_LOOKUP, + &Attribute::MAP, ]; for test_attrs in tests { let mut attrs = Attributes::new(); @@ -1060,13 +1069,6 @@ fn test_attributes_many() { .map(|attr| *attr as u16) .collect::>() ); - assert_eq!( - attrs.ansi_nums().collect::>(), - test_attrs - .iter() - .map(|attr| *attr as u16 + 1) - .collect::>() - ); assert_eq!(&attrs.attrs().collect::>(), test_attrs); } }