diff --git a/src/ansi.rs b/src/ansi.rs index 6f46dee..722ccb9 100644 --- a/src/ansi.rs +++ b/src/ansi.rs @@ -15,7 +15,7 @@ impl Style { // Prefix everything with reset characters if needed if self.prefix_with_reset { - write!(f, "\x1B[0m")? + write!(f, "\x1B[0m")?; } // Write the codes’ prefix, then write numbers, separated by @@ -31,33 +31,33 @@ impl Style { written_anything = true; #[cfg(feature = "gnu_legacy")] write!(f, "0")?; - write!(f, "{}", c)?; + write!(f, "{c}")?; Ok(()) }; if self.is_bold { - write_char('1')? + write_char('1')?; } if self.is_dimmed { - write_char('2')? + write_char('2')?; } if self.is_italic { - write_char('3')? + write_char('3')?; } if self.is_underline { - write_char('4')? + write_char('4')?; } if self.is_blink { - write_char('5')? + write_char('5')?; } if self.is_reverse { - write_char('7')? + write_char('7')?; } if self.is_hidden { - write_char('8')? + write_char('8')?; } if self.is_strikethrough { - write_char('9')? + write_char('9')?; } } @@ -111,7 +111,7 @@ impl Style { if self.is_plain() { Ok(()) } else { - write!(f, "{}", RESET) + write!(f, "{RESET}") } } } @@ -131,8 +131,8 @@ impl Color { Color::Magenta => write!(f, "35"), Color::Cyan => write!(f, "36"), Color::White => write!(f, "37"), - Color::Fixed(num) => write!(f, "38;5;{}", num), - Color::Rgb(r, g, b) => write!(f, "38;2;{};{};{}", r, g, b), + Color::Fixed(num) => write!(f, "38;5;{num}"), + Color::Rgb(r, g, b) => write!(f, "38;2;{r};{g};{b}"), Color::Default => write!(f, "39"), Color::DarkGray => write!(f, "90"), Color::LightRed => write!(f, "91"), @@ -157,8 +157,8 @@ impl Color { Color::Magenta => write!(f, "45"), Color::Cyan => write!(f, "46"), Color::White => write!(f, "47"), - Color::Fixed(num) => write!(f, "48;5;{}", num), - Color::Rgb(r, g, b) => write!(f, "48;2;{};{};{}", r, g, b), + Color::Fixed(num) => write!(f, "48;5;{num}"), + Color::Rgb(r, g, b) => write!(f, "48;2;{r};{g};{b}"), Color::Default => write!(f, "49"), Color::DarkGray => write!(f, "100"), Color::LightRed => write!(f, "101"), @@ -226,7 +226,7 @@ impl Style { /// # } /// ``` /// - /// # Examples with gnu_legacy feature enabled + /// # Examples with `gnu_legacy` feature enabled /// Styles like bold, underlined, etc. are two-digit now /// /// ``` @@ -243,6 +243,7 @@ impl Style { /// style.prefix().to_string()); /// # } /// ``` + #[must_use] pub const fn prefix(self) -> Prefix { Prefix(self) } @@ -270,7 +271,7 @@ impl Style { /// style.infix(style).to_string()); /// # } /// ``` - /// # Examples with gnu_legacy feature enabled + /// # Examples with `gnu_legacy` feature enabled /// Styles like bold, underlined, etc. are two-digit now /// ``` /// # #[cfg(feature = "gnu_legacy")] @@ -282,6 +283,7 @@ impl Style { /// style.infix(Green.bold()).to_string()); /// # } /// ``` + #[must_use] pub const fn infix(self, next: Style) -> Infix { Infix(self, next) } @@ -306,6 +308,7 @@ impl Style { /// assert_eq!("", /// style.suffix().to_string()); /// ``` + #[must_use] pub const fn suffix(self) -> Suffix { Suffix(self) } @@ -325,6 +328,7 @@ impl Color { /// assert_eq!("\x1b[32m", /// Green.prefix().to_string()); /// ``` + #[must_use] pub fn prefix(self) -> Prefix { Prefix(self.normal()) } @@ -343,6 +347,7 @@ impl Color { /// assert_eq!("\x1b[33m", /// Red.infix(Yellow).to_string()); /// ``` + #[must_use] pub fn infix(self, next: Color) -> Infix { Infix(self.normal(), next.normal()) } @@ -360,6 +365,7 @@ impl Color { /// assert_eq!("\x1b[0m", /// Purple.suffix().to_string()); /// ``` + #[must_use] pub fn suffix(self) -> Suffix { Suffix(self.normal()) } diff --git a/src/debug.rs b/src/debug.rs index 6997bab..02e003e 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -34,52 +34,52 @@ impl fmt::Debug for Style { if let Some(fg) = self.foreground { if written_anything { - fmt.write_str(", ")? + fmt.write_str(", ")?; } written_anything = true; - write!(fmt, "fg({:?})", fg)? + write!(fmt, "fg({fg:?})")?; } if let Some(bg) = self.background { if written_anything { - fmt.write_str(", ")? + fmt.write_str(", ")?; } written_anything = true; - write!(fmt, "on({:?})", bg)? + write!(fmt, "on({bg:?})")?; } { let mut write_flag = |name| { if written_anything { - fmt.write_str(", ")? + fmt.write_str(", ")?; } written_anything = true; fmt.write_str(name) }; if self.is_blink { - write_flag("blink")? + write_flag("blink")?; } if self.is_bold { - write_flag("bold")? + write_flag("bold")?; } if self.is_dimmed { - write_flag("dimmed")? + write_flag("dimmed")?; } if self.is_hidden { - write_flag("hidden")? + write_flag("hidden")?; } if self.is_italic { - write_flag("italic")? + write_flag("italic")?; } if self.is_reverse { - write_flag("reverse")? + write_flag("reverse")?; } if self.is_strikethrough { - write_flag("strikethrough")? + write_flag("strikethrough")?; } if self.is_underline { - write_flag("underline")? + write_flag("underline")?; } } @@ -133,10 +133,10 @@ mod test { }"; let style = Blue.bold(); - let style_fmt_debug = format!("{:?}", style); - let style_fmt_pretty = format!("{:#?}", style); - println!("style_fmt_debug:\n{}", style_fmt_debug); - println!("style_fmt_pretty:\n{}", style_fmt_pretty); + let style_fmt_debug = format!("{style:?}"); + let style_fmt_pretty = format!("{style:#?}"); + println!("style_fmt_debug:\n{style_fmt_debug}"); + println!("style_fmt_pretty:\n{style_fmt_pretty}"); assert_eq!(expected_debug, style_fmt_debug); assert_eq!(expected_pretty_repat, style_fmt_pretty); diff --git a/src/difference.rs b/src/difference.rs index 30a88f1..fd596c0 100644 --- a/src/difference.rs +++ b/src/difference.rs @@ -33,7 +33,7 @@ impl Difference { /// happen, this function returns None, meaning that the entire set of /// styles should be reset and begun again. pub fn between(first: &Style, next: &Style) -> Difference { - use self::Difference::*; + use self::Difference::{Empty, ExtraStyles, Reset}; // XXX(Havvy): This algorithm is kind of hard to replicate without // having the Plain/Foreground enum variants, so I'm just leaving diff --git a/src/display.rs b/src/display.rs index cfc1aec..3a5f1d7 100644 --- a/src/display.rs +++ b/src/display.rs @@ -218,6 +218,7 @@ pub type AnsiStrings<'a> = AnsiGenericStrings<'a, str>; /// A function to construct an `AnsiStrings` instance. #[allow(non_snake_case)] +#[must_use] pub const fn AnsiStrings<'a>(arg: &'a [AnsiString<'a>]) -> AnsiStrings<'a> { AnsiGenericStrings(arg) } @@ -228,6 +229,7 @@ pub type AnsiByteStrings<'a> = AnsiGenericStrings<'a, [u8]>; /// A function to construct an `AnsiByteStrings` instance. #[allow(non_snake_case)] +#[must_use] pub const fn AnsiByteStrings<'a>(arg: &'a [AnsiByteString<'a>]) -> AnsiByteStrings<'a> { AnsiGenericStrings(arg) } @@ -347,7 +349,7 @@ where &'a S: AsRef<[u8]>, { fn write_to_any + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> { - use self::Difference::*; + use self::Difference::{Empty, ExtraStyles, Reset}; let first = match self.0.first() { None => return Ok(()), @@ -372,7 +374,7 @@ where // have already been written by this point. if let Some(last) = self.0.last() { if !last.style.is_plain() { - write!(w, "{}", RESET)?; + write!(w, "{RESET}")?; } } @@ -409,54 +411,34 @@ mod tests { assert!(joined.starts_with("\x1B[32mBefore is Green. \x1B[0m")); assert!( joined.ends_with(unstyled_s.as_str()), - "{:?} does not end with {:?}", - joined, - unstyled_s + "{joined:?} does not end with {unstyled_s:?}" ); // check that RESET does not follow unstyled when appending styled let joined = AnsiStrings(&[unstyled.clone(), after_g.clone()]).to_string(); assert!( joined.starts_with(unstyled_s.as_str()), - "{:?} does not start with {:?}", - joined, - unstyled_s + "{joined:?} does not start with {unstyled_s:?}" ); assert!(joined.ends_with("\x1B[32m After is Green.\x1B[0m")); // does not introduce spurious SGR codes (reset or otherwise) adjacent // to plain strings let joined = AnsiStrings(&[unstyled.clone()]).to_string(); - assert!( - !joined.contains("\x1B["), - "{:?} does contain \\x1B[", - joined - ); + assert!(!joined.contains("\x1B["), "{joined:?} does contain \\x1B["); let joined = AnsiStrings(&[before.clone(), unstyled.clone()]).to_string(); - assert!( - !joined.contains("\x1B["), - "{:?} does contain \\x1B[", - joined - ); + assert!(!joined.contains("\x1B["), "{joined:?} does contain \\x1B["); let joined = AnsiStrings(&[before.clone(), unstyled.clone(), after.clone()]).to_string(); - assert!( - !joined.contains("\x1B["), - "{:?} does contain \\x1B[", - joined - ); + assert!(!joined.contains("\x1B["), "{joined:?} does contain \\x1B["); let joined = AnsiStrings(&[unstyled.clone(), after.clone()]).to_string(); - assert!( - !joined.contains("\x1B["), - "{:?} does contain \\x1B[", - joined - ); + assert!(!joined.contains("\x1B["), "{joined:?} does contain \\x1B["); } #[test] fn title() { let title = AnsiGenericString::title("Test Title"); assert_eq!(title.clone().to_string(), "\x1B]2;Test Title\x1B\\"); - idempotent(title) + idempotent(title); } #[test] diff --git a/src/gradient.rs b/src/gradient.rs index 00f5636..4519d8b 100644 --- a/src/gradient.rs +++ b/src/gradient.rs @@ -13,10 +13,12 @@ pub struct Gradient { impl Gradient { /// Creates a new [Gradient] with two [Rgb] colors, `start` and `end` #[inline] + #[must_use] pub const fn new(start: Rgb, end: Rgb) -> Self { Self { start, end } } + #[must_use] pub const fn from_color_rgb(start: Color, end: Color) -> Self { let start_grad = match start { Color::Rgb(r, g, b) => Rgb { r, g, b }, @@ -34,16 +36,19 @@ impl Gradient { } /// Computes the [Rgb] color between `start` and `end` for `t` + #[must_use] pub fn at(&self, t: f32) -> Rgb { self.start.lerp(self.end, t) } /// Returns the reverse of `self` #[inline] + #[must_use] pub const fn reverse(&self) -> Self { Self::new(self.end, self.start) } + #[must_use] pub fn build(&self, text: &str, target: TargetGround) -> String { let delta = 1.0 / text.len() as f32; let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| { @@ -61,6 +66,7 @@ impl Gradient { } } +#[must_use] pub fn build_all_gradient_text(text: &str, foreground: Gradient, background: Gradient) -> String { let delta = 1.0 / text.len() as f32; let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| { @@ -91,6 +97,7 @@ pub enum TargetGround { impl TargetGround { #[inline] + #[must_use] pub const fn code(&self) -> u8 { match self { Self::Foreground => 30, diff --git a/src/rgb.rs b/src/rgb.rs index d4c0acd..0082253 100644 --- a/src/rgb.rs +++ b/src/rgb.rs @@ -14,16 +14,19 @@ pub struct Rgb { impl Rgb { /// Creates a new [Rgb] color #[inline] + #[must_use] pub const fn new(r: u8, g: u8, b: u8) -> Self { Self { r, g, b } } /// Creates a new [Rgb] color with a hex code #[inline] + #[must_use] pub const fn from_hex(hex: u32) -> Self { Self::new((hex >> 16) as u8, (hex >> 8) as u8, hex as u8) } + #[must_use] pub fn from_hex_string(hex: String) -> Self { if hex.chars().count() == 8 && hex.starts_with("0x") { // eprintln!("hex:{:?}", hex); @@ -48,6 +51,7 @@ impl Rgb { } /// Creates a new [Rgb] color with three [f32] values + #[must_use] pub fn from_f32(r: f32, g: f32, b: f32) -> Self { Self::new( (r.clamp(0.0, 1.0) * 255.0) as u8, @@ -58,11 +62,13 @@ impl Rgb { /// Creates a grayscale [Rgb] color #[inline] + #[must_use] pub const fn gray(x: u8) -> Self { Self::new(x, x, x) } /// Creates a grayscale [Rgb] color with a [f32] value + #[must_use] pub fn gray_f32(x: f32) -> Self { Self::from_f32(x, x, x) } @@ -96,6 +102,7 @@ impl Rgb { // } /// Computes the linear interpolation between `self` and `other` for `t` + #[must_use] pub fn lerp(&self, other: Self, t: f32) -> Self { let t = t.clamp(0.0, 1.0); self * (1.0 - t) + other * t @@ -140,9 +147,9 @@ const fn rgb_sub(lhs: &Rgb, rhs: &Rgb) -> Rgb { fn rgb_mul_f32(lhs: &Rgb, rhs: &f32) -> Rgb { Rgb::new( - (lhs.r as f32 * rhs.clamp(0.0, 1.0)) as u8, - (lhs.g as f32 * rhs.clamp(0.0, 1.0)) as u8, - (lhs.b as f32 * rhs.clamp(0.0, 1.0)) as u8, + (f32::from(lhs.r) * rhs.clamp(0.0, 1.0)) as u8, + (f32::from(lhs.g) * rhs.clamp(0.0, 1.0)) as u8, + (f32::from(lhs.b) * rhs.clamp(0.0, 1.0)) as u8, ) } diff --git a/src/style.rs b/src/style.rs index 3058767..84b4556 100644 --- a/src/style.rs +++ b/src/style.rs @@ -60,6 +60,7 @@ impl Style { /// let style = Style::new(); /// println!("{}", style.paint("hi")); /// ``` + #[must_use] pub fn new() -> Style { Style::default() } @@ -74,6 +75,7 @@ impl Style { /// let style = Style::new().reset_before_style(); /// println!("{}", style.paint("hey")); /// ``` + #[must_use] pub const fn reset_before_style(&self) -> Style { Style { prefix_with_reset: true, @@ -91,6 +93,7 @@ impl Style { /// let style = Style::new().bold(); /// println!("{}", style.paint("hey")); /// ``` + #[must_use] pub const fn bold(&self) -> Style { Style { is_bold: true, @@ -108,6 +111,7 @@ impl Style { /// let style = Style::new().dimmed(); /// println!("{}", style.paint("sup")); /// ``` + #[must_use] pub const fn dimmed(&self) -> Style { Style { is_dimmed: true, @@ -125,6 +129,7 @@ impl Style { /// let style = Style::new().italic(); /// println!("{}", style.paint("greetings")); /// ``` + #[must_use] pub const fn italic(&self) -> Style { Style { is_italic: true, @@ -142,6 +147,7 @@ impl Style { /// let style = Style::new().underline(); /// println!("{}", style.paint("salutations")); /// ``` + #[must_use] pub const fn underline(&self) -> Style { Style { is_underline: true, @@ -158,6 +164,7 @@ impl Style { /// let style = Style::new().blink(); /// println!("{}", style.paint("wazzup")); /// ``` + #[must_use] pub const fn blink(&self) -> Style { Style { is_blink: true, @@ -175,6 +182,7 @@ impl Style { /// let style = Style::new().reverse(); /// println!("{}", style.paint("aloha")); /// ``` + #[must_use] pub const fn reverse(&self) -> Style { Style { is_reverse: true, @@ -192,6 +200,7 @@ impl Style { /// let style = Style::new().hidden(); /// println!("{}", style.paint("ahoy")); /// ``` + #[must_use] pub const fn hidden(&self) -> Style { Style { is_hidden: true, @@ -209,6 +218,7 @@ impl Style { /// let style = Style::new().strikethrough(); /// println!("{}", style.paint("yo")); /// ``` + #[must_use] pub const fn strikethrough(&self) -> Style { Style { is_strikethrough: true, @@ -226,6 +236,7 @@ impl Style { /// let style = Style::new().fg(Color::Yellow); /// println!("{}", style.paint("hi")); /// ``` + #[must_use] pub const fn fg(&self, foreground: Color) -> Style { Style { foreground: Some(foreground), @@ -243,6 +254,7 @@ impl Style { /// let style = Style::new().on(Color::Blue); /// println!("{}", style.paint("eyyyy")); /// ``` + #[must_use] pub const fn on(&self, background: Color) -> Style { Style { background: Some(background), @@ -261,6 +273,7 @@ impl Style { /// assert_eq!(true, Style::default().is_plain()); /// assert_eq!(false, Style::default().bold().is_plain()); /// ``` + #[must_use] pub fn is_plain(self) -> bool { self == Style::default() } @@ -404,6 +417,7 @@ impl Color { /// let style = Color::Red.normal(); /// println!("{}", style.paint("hi")); /// ``` + #[must_use] pub fn normal(self) -> Style { Style { foreground: Some(self), @@ -422,6 +436,7 @@ impl Color { /// let style = Color::Green.bold(); /// println!("{}", style.paint("hey")); /// ``` + #[must_use] pub fn bold(self) -> Style { Style { foreground: Some(self), @@ -441,6 +456,7 @@ impl Color { /// let style = Color::Yellow.dimmed(); /// println!("{}", style.paint("sup")); /// ``` + #[must_use] pub fn dimmed(self) -> Style { Style { foreground: Some(self), @@ -460,6 +476,7 @@ impl Color { /// let style = Color::Blue.italic(); /// println!("{}", style.paint("greetings")); /// ``` + #[must_use] pub fn italic(self) -> Style { Style { foreground: Some(self), @@ -479,6 +496,7 @@ impl Color { /// let style = Color::Purple.underline(); /// println!("{}", style.paint("salutations")); /// ``` + #[must_use] pub fn underline(self) -> Style { Style { foreground: Some(self), @@ -498,6 +516,7 @@ impl Color { /// let style = Color::Cyan.blink(); /// println!("{}", style.paint("wazzup")); /// ``` + #[must_use] pub fn blink(self) -> Style { Style { foreground: Some(self), @@ -517,6 +536,7 @@ impl Color { /// let style = Color::Black.reverse(); /// println!("{}", style.paint("aloha")); /// ``` + #[must_use] pub fn reverse(self) -> Style { Style { foreground: Some(self), @@ -536,6 +556,7 @@ impl Color { /// let style = Color::White.hidden(); /// println!("{}", style.paint("ahoy")); /// ``` + #[must_use] pub fn hidden(self) -> Style { Style { foreground: Some(self), @@ -555,6 +576,7 @@ impl Color { /// let style = Color::Fixed(244).strikethrough(); /// println!("{}", style.paint("yo")); /// ``` + #[must_use] pub fn strikethrough(self) -> Style { Style { foreground: Some(self), @@ -574,6 +596,7 @@ impl Color { /// let style = Color::Fixed(244).reset_before_style(); /// println!("{}", style.paint("yo")); /// ``` + #[must_use] pub fn reset_before_style(self) -> Style { Style { foreground: Some(self), @@ -593,6 +616,7 @@ impl Color { /// let style = Color::Rgb(31, 31, 31).on(Color::White); /// println!("{}", style.paint("eyyyy")); /// ``` + #[must_use] pub fn on(self, background: Color) -> Style { Style { foreground: Some(self), diff --git a/src/util.rs b/src/util.rs index f1ed36f..61fbf86 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,13 +1,13 @@ use crate::display::{AnsiString, AnsiStrings}; -use std::ops::Deref; -/// Return a substring of the given AnsiStrings sequence, while keeping the formatting. +/// Return a substring of the given `AnsiStrings` sequence, while keeping the formatting. +#[must_use] pub fn sub_string(start: usize, len: usize, strs: &AnsiStrings) -> Vec> { let mut vec = Vec::new(); let mut pos = start; let mut len_rem = len; - for i in strs.0.iter() { + for i in strs.0 { let frag_len = i.string.len(); if pos >= frag_len { pos -= frag_len; @@ -34,20 +34,22 @@ pub fn sub_string(start: usize, len: usize, strs: &AnsiStrings) -> Vec String { let mut s = String::new(); - for i in strs.0.iter() { - s += i.string.deref(); + for i in strs.0 { + s += &*i.string; } s } -/// Return the unstyled length of AnsiStrings. This is equaivalent to `unstyle(strs).len()`. +/// Return the unstyled length of `AnsiStrings`. This is equivalent to `unstyle(strs).len()`. +#[must_use] pub fn unstyled_len(strs: &AnsiStrings) -> usize { let mut l = 0; - for i in strs.0.iter() { + for i in strs.0 { l += i.string.len(); } l