From 6e7778e7d74c3f92726beca5a7b6d3a4cd4d7941 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 28 Mar 2024 12:45:17 -0500 Subject: [PATCH] style: Update for new lints --- crates/anstream/benches/stream.rs | 15 +++--- crates/anstream/benches/strip.rs | 13 +++-- crates/anstream/benches/wincon.rs | 3 +- crates/anstream/examples/dump-stream.rs | 7 ++- crates/anstream/examples/query-stream.rs | 2 + crates/anstream/src/adapter/strip.rs | 20 +++---- crates/anstream/src/adapter/wincon.rs | 12 +++-- crates/anstream/src/auto.rs | 1 + crates/anstream/src/lib.rs | 2 + crates/anstream/src/stream.rs | 5 ++ crates/anstream/src/strip.rs | 1 + crates/anstyle-ansi-term/README.md | 2 +- crates/anstyle-ansi-term/src/lib.rs | 19 ++----- crates/anstyle-crossterm/README.md | 2 +- crates/anstyle-crossterm/src/lib.rs | 19 ++----- crates/anstyle-git/src/lib.rs | 52 +++++++------------ crates/anstyle-lossy/src/lib.rs | 31 +++++++++++ crates/anstyle-lossy/src/palette.rs | 24 +++++---- crates/anstyle-ls/src/lib.rs | 32 +++--------- crates/anstyle-owo-colors/README.md | 2 +- crates/anstyle-owo-colors/src/lib.rs | 20 ++----- crates/anstyle-parse/benches/parse.rs | 17 +++--- crates/anstyle-parse/src/lib.rs | 8 ++- crates/anstyle-parse/src/state/codegen.rs | 2 +- crates/anstyle-parse/src/state/definitions.rs | 6 ++- crates/anstyle-parse/src/state/mod.rs | 2 + crates/anstyle-query/examples/query.rs | 2 + crates/anstyle-query/src/lib.rs | 2 + crates/anstyle-query/src/windows.rs | 2 +- crates/anstyle-roff/src/lib.rs | 18 +++---- crates/anstyle-roff/src/styled_str.rs | 42 ++++++++------- crates/anstyle-svg/src/lib.rs | 16 +++--- crates/anstyle-syntect/README.md | 2 +- crates/anstyle-syntect/src/lib.rs | 22 +++----- crates/anstyle-termcolor/README.md | 2 +- crates/anstyle-termcolor/src/lib.rs | 20 ++----- crates/anstyle-wincon/examples/dump-wincon.rs | 4 +- crates/anstyle-wincon/examples/set-wincon.rs | 4 +- crates/anstyle-wincon/src/stream.rs | 12 ++--- crates/anstyle-yansi/README.md | 2 +- crates/anstyle-yansi/src/lib.rs | 20 ++----- crates/anstyle/examples/dump-style.rs | 8 ++- crates/anstyle/src/color.rs | 42 +++++++++++---- crates/anstyle/src/effect.rs | 12 ++++- crates/anstyle/src/lib.rs | 3 +- crates/anstyle/src/reset.rs | 3 +- crates/anstyle/src/style.rs | 13 +++-- crates/colorchoice-clap/src/lib.rs | 3 +- crates/colorchoice/src/lib.rs | 20 ++++--- 49 files changed, 316 insertions(+), 277 deletions(-) diff --git a/crates/anstream/benches/stream.rs b/crates/anstream/benches/stream.rs index f89aacf5..70bbe78b 100644 --- a/crates/anstream/benches/stream.rs +++ b/crates/anstream/benches/stream.rs @@ -1,3 +1,6 @@ +#![allow(missing_docs)] +#![allow(clippy::unwrap_used)] + use std::io::Write as _; use criterion::{black_box, Criterion}; @@ -21,7 +24,7 @@ fn stream(c: &mut Criterion) { stream.write_all(content).unwrap(); black_box(stream) - }) + }); }); group.bench_function("StripStream", |b| { b.iter(|| { @@ -31,7 +34,7 @@ fn stream(c: &mut Criterion) { stream.write_all(content).unwrap(); black_box(stream) - }) + }); }); #[cfg(all(windows, feature = "wincon"))] group.bench_function("WinconStream", |b| { @@ -42,7 +45,7 @@ fn stream(c: &mut Criterion) { stream.write_all(content).unwrap(); black_box(stream) - }) + }); }); group.bench_function("AutoStream::always_ansi", |b| { b.iter(|| { @@ -52,7 +55,7 @@ fn stream(c: &mut Criterion) { stream.write_all(content).unwrap(); black_box(stream) - }) + }); }); group.bench_function("AutoStream::always", |b| { b.iter(|| { @@ -62,7 +65,7 @@ fn stream(c: &mut Criterion) { stream.write_all(content).unwrap(); black_box(stream) - }) + }); }); group.bench_function("AutoStream::never", |b| { b.iter(|| { @@ -72,7 +75,7 @@ fn stream(c: &mut Criterion) { stream.write_all(content).unwrap(); black_box(stream) - }) + }); }); } } diff --git a/crates/anstream/benches/strip.rs b/crates/anstream/benches/strip.rs index 9ed6178c..a9ccdcd5 100644 --- a/crates/anstream/benches/strip.rs +++ b/crates/anstream/benches/strip.rs @@ -1,3 +1,6 @@ +#![allow(missing_docs)] +#![allow(clippy::unwrap_used)] + use criterion::{black_box, Criterion}; #[derive(Default)] @@ -59,14 +62,14 @@ fn strip(c: &mut Criterion) { } black_box(stripped.0) - }) + }); }); group.bench_function("strip_ansi_escapes", |b| { b.iter(|| { let stripped = strip_ansi_escapes::strip(content); black_box(stripped) - }) + }); }); if let Ok(content) = std::str::from_utf8(content) { group.bench_function("strip_str", |b| { @@ -74,7 +77,7 @@ fn strip(c: &mut Criterion) { let stripped = anstream::adapter::strip_str(content).to_string(); black_box(stripped) - }) + }); }); group.bench_function("StripStr", |b| { b.iter(|| { @@ -85,7 +88,7 @@ fn strip(c: &mut Criterion) { } black_box(stripped) - }) + }); }); } group.bench_function("strip_bytes", |b| { @@ -93,7 +96,7 @@ fn strip(c: &mut Criterion) { let stripped = anstream::adapter::strip_bytes(content).into_vec(); black_box(stripped) - }) + }); }); } } diff --git a/crates/anstream/benches/wincon.rs b/crates/anstream/benches/wincon.rs index 54e1f80a..3506c659 100644 --- a/crates/anstream/benches/wincon.rs +++ b/crates/anstream/benches/wincon.rs @@ -1,3 +1,4 @@ +#![allow(missing_docs)] use criterion::{black_box, Criterion}; fn wincon(c: &mut Criterion) { @@ -17,7 +18,7 @@ fn wincon(c: &mut Criterion) { let stripped = state.extract_next(content).collect::>(); black_box(stripped) - }) + }); }); } } diff --git a/crates/anstream/examples/dump-stream.rs b/crates/anstream/examples/dump-stream.rs index 8d80ce88..00f53334 100644 --- a/crates/anstream/examples/dump-stream.rs +++ b/crates/anstream/examples/dump-stream.rs @@ -1,3 +1,5 @@ +//! Write colored text, adapting to the terminals capabilities + use std::io::Write; fn main() -> Result<(), lexopt::Error> { @@ -6,7 +8,9 @@ fn main() -> Result<(), lexopt::Error> { let mut stdout = stdout.lock(); for fixed in 0..16 { - let color = anstyle::Ansi256Color(fixed).into_ansi().unwrap(); + let color = anstyle::Ansi256Color(fixed) + .into_ansi() + .expect("within 4-bit color range"); let style = style(color, args.layer, args.effects); let _ = print_number(&mut stdout, fixed, style); if fixed == 7 || fixed == 15 { @@ -70,6 +74,7 @@ enum Layer { impl Args { fn parse() -> Result { + #[allow(clippy::wildcard_imports)] // false positive use lexopt::prelude::*; let mut res = Args::default(); diff --git a/crates/anstream/examples/query-stream.rs b/crates/anstream/examples/query-stream.rs index fe0af95a..1c8670ec 100644 --- a/crates/anstream/examples/query-stream.rs +++ b/crates/anstream/examples/query-stream.rs @@ -1,3 +1,5 @@ +//! Report a terminal's capabilities + fn main() { println!("stdout:"); println!( diff --git a/crates/anstream/src/adapter/strip.rs b/crates/anstream/src/adapter/strip.rs index a8d67f80..fc0c1de8 100644 --- a/crates/anstream/src/adapter/strip.rs +++ b/crates/anstream/src/adapter/strip.rs @@ -145,11 +145,13 @@ fn next_str<'s>(bytes: &mut &'s [u8], state: &mut State) -> Option<&'s str> { #[inline] unsafe fn from_utf8_unchecked<'b>(bytes: &'b [u8], safety_justification: &'static str) -> &'b str { - if cfg!(debug_assertions) { - // Catch problems more quickly when testing - std::str::from_utf8(bytes).expect(safety_justification) - } else { - std::str::from_utf8_unchecked(bytes) + unsafe { + if cfg!(debug_assertions) { + // Catch problems more quickly when testing + std::str::from_utf8(bytes).expect(safety_justification) + } else { + std::str::from_utf8_unchecked(bytes) + } } } @@ -327,7 +329,7 @@ fn next_bytes<'s>( } #[derive(Default, Clone, Debug, PartialEq, Eq)] -pub struct Utf8Parser { +pub(crate) struct Utf8Parser { utf8_parser: utf8parse::Parser, } @@ -440,7 +442,7 @@ mod test { fn test_strip_byte_multibyte() { let bytes = [240, 145, 141, 139]; let expected = parser_strip(&bytes); - let actual = String::from_utf8(strip_byte(&bytes).to_vec()).unwrap(); + let actual = String::from_utf8(strip_byte(&bytes).clone()).unwrap(); assert_eq!(expected, actual); } @@ -456,7 +458,7 @@ mod test { fn test_strip_byte_del() { let bytes = [0x7f]; let expected = ""; - let actual = String::from_utf8(strip_byte(&bytes).to_vec()).unwrap(); + let actual = String::from_utf8(strip_byte(&bytes).clone()).unwrap(); assert_eq!(expected, actual); } @@ -502,7 +504,7 @@ mod test { dbg!(&s); dbg!(s.as_bytes()); let expected = parser_strip(s.as_bytes()); - let actual = String::from_utf8(strip_byte(s.as_bytes()).to_vec()).unwrap(); + let actual = String::from_utf8(strip_byte(s.as_bytes()).clone()).unwrap(); assert_eq!(expected, actual); } } diff --git a/crates/anstream/src/adapter/wincon.rs b/crates/anstream/src/adapter/wincon.rs index b0996838..f879e828 100644 --- a/crates/anstream/src/adapter/wincon.rs +++ b/crates/anstream/src/adapter/wincon.rs @@ -150,7 +150,7 @@ impl anstyle_parse::Perform for WinconCapture { break; } (State::Normal, 30..=37) => { - let color = to_ansi_color(value - 30).unwrap(); + let color = to_ansi_color(value - 30).expect("within 4-bit range"); style = style.fg_color(Some(color.into())); break; } @@ -163,7 +163,7 @@ impl anstyle_parse::Perform for WinconCapture { break; } (State::Normal, 40..=47) => { - let color = to_ansi_color(value - 40).unwrap(); + let color = to_ansi_color(value - 40).expect("within 4-bit range"); style = style.bg_color(Some(color.into())); break; } @@ -180,12 +180,16 @@ impl anstyle_parse::Perform for WinconCapture { state = State::PrepareCustomColor; } (State::Normal, 90..=97) => { - let color = to_ansi_color(value - 90).unwrap().bright(true); + let color = to_ansi_color(value - 90) + .expect("within 4-bit range") + .bright(true); style = style.fg_color(Some(color.into())); break; } (State::Normal, 100..=107) => { - let color = to_ansi_color(value - 100).unwrap().bright(true); + let color = to_ansi_color(value - 100) + .expect("within 4-bit range") + .bright(true); style = style.bg_color(Some(color.into())); break; } diff --git a/crates/anstream/src/auto.rs b/crates/anstream/src/auto.rs index ead08f77..743640f8 100644 --- a/crates/anstream/src/auto.rs +++ b/crates/anstream/src/auto.rs @@ -157,6 +157,7 @@ where } } + /// Returns `true` if the descriptor/handle refers to a terminal/tty. #[inline] pub fn is_terminal(&self) -> bool { match &self.inner { diff --git a/crates/anstream/src/lib.rs b/crates/anstream/src/lib.rs index 6a50fc95..c3400d71 100644 --- a/crates/anstream/src/lib.rs +++ b/crates/anstream/src/lib.rs @@ -56,7 +56,9 @@ pub use wincon::WinconStream; #[allow(deprecated)] pub use buffer::Buffer; +/// An adaptive wrapper around the global standard output stream of the current process pub type Stdout = AutoStream; +/// An adaptive wrapper around the global standard error stream of the current process pub type Stderr = AutoStream; /// Create an ANSI escape code compatible stdout diff --git a/crates/anstream/src/stream.rs b/crates/anstream/src/stream.rs index e2f7e68d..3a956d68 100644 --- a/crates/anstream/src/stream.rs +++ b/crates/anstream/src/stream.rs @@ -41,7 +41,9 @@ impl RawStream for crate::Buffer {} #[allow(deprecated)] impl RawStream for &'_ mut crate::Buffer {} +/// Trait to determine if a descriptor/handle refers to a terminal/tty. pub trait IsTerminal: private::Sealed { + /// Returns `true` if the descriptor/handle refers to a terminal/tty. fn is_terminal(&self) -> bool; } @@ -145,11 +147,14 @@ impl IsTerminal for &'_ mut crate::Buffer { } } +/// Lock a stream pub trait AsLockedWrite: private::Sealed { + /// Locked writer type type Write<'w>: RawStream + 'w where Self: 'w; + /// Lock a stream fn as_locked_write(&mut self) -> Self::Write<'_>; } diff --git a/crates/anstream/src/strip.rs b/crates/anstream/src/strip.rs index 2d1168ce..9f0d28bd 100644 --- a/crates/anstream/src/strip.rs +++ b/crates/anstream/src/strip.rs @@ -37,6 +37,7 @@ where S: std::io::Write, S: IsTerminal, { + /// Returns `true` if the descriptor/handle refers to a terminal/tty. #[inline] pub fn is_terminal(&self) -> bool { self.raw.is_terminal() diff --git a/crates/anstyle-ansi-term/README.md b/crates/anstyle-ansi-term/README.md index 44fdffa6..c5a37118 100644 --- a/crates/anstyle-ansi-term/README.md +++ b/crates/anstyle-ansi-term/README.md @@ -1,6 +1,6 @@ # anstyle-ansi-term -> Convert from color styling types to [`ansi_term`](https://lib.rs/ansi_term) color types +> Convert between [`ansi_term`](https://lib.rs/ansi_term) and generic styling types [![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation] ![License](https://img.shields.io/crates/l/anstyle-ansi-term.svg) diff --git a/crates/anstyle-ansi-term/src/lib.rs b/crates/anstyle-ansi-term/src/lib.rs index 9be2b3e3..2f2d1513 100644 --- a/crates/anstyle-ansi-term/src/lib.rs +++ b/crates/anstyle-ansi-term/src/lib.rs @@ -1,23 +1,10 @@ +//! Convert between [`ansi_term`](https://lib.rs/ansi_term) and generic styling types + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed { - fn to_ansi_term(self) -> ansi_term::Style; -} - -impl sealed::Sealed for anstyle::Style {} - -impl Ext for anstyle::Style { - fn to_ansi_term(self) -> ansi_term::Style { - to_ansi_term(self) - } -} - +/// Adapt generic styling to [`ansi_term`] pub fn to_ansi_term(astyle: anstyle::Style) -> ansi_term::Style { let mut style = ansi_term::Style::new(); diff --git a/crates/anstyle-crossterm/README.md b/crates/anstyle-crossterm/README.md index 7a2a1341..dd03ddd2 100644 --- a/crates/anstyle-crossterm/README.md +++ b/crates/anstyle-crossterm/README.md @@ -1,6 +1,6 @@ # anstyle-crossterm -> Convert from color styling types to [`crossterm`](https://lib.rs/crossterm) color types +> Convert between [`crossterm`](https://lib.rs/crossterm) and generic styling types [![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation] ![License](https://img.shields.io/crates/l/anstyle-crossterm.svg) diff --git a/crates/anstyle-crossterm/src/lib.rs b/crates/anstyle-crossterm/src/lib.rs index 0729833f..d3305598 100644 --- a/crates/anstyle-crossterm/src/lib.rs +++ b/crates/anstyle-crossterm/src/lib.rs @@ -1,23 +1,10 @@ +//! Convert between [`crossterm`](https://lib.rs/crossterm) and [generic styling types][anstyle] + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed { - fn to_crossterm(self) -> crossterm::style::ContentStyle; -} - -impl sealed::Sealed for anstyle::Style {} - -impl Ext for anstyle::Style { - fn to_crossterm(self) -> crossterm::style::ContentStyle { - to_crossterm(self) - } -} - +/// Adapt generic styling to [`crossterm`] pub fn to_crossterm(astyle: anstyle::Style) -> crossterm::style::ContentStyle { let foreground_color = astyle.get_fg_color().map(to_ansi_color); let background_color = astyle.get_bg_color().map(to_ansi_color); diff --git a/crates/anstyle-git/src/lib.rs b/crates/anstyle-git/src/lib.rs index a52d10d2..ef13479c 100644 --- a/crates/anstyle-git/src/lib.rs +++ b/crates/anstyle-git/src/lib.rs @@ -15,24 +15,8 @@ #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed + Sized { - fn parse_git(s: &str) -> Result; -} - -impl sealed::Sealed for anstyle::Style {} - -impl Ext for anstyle::Style { - fn parse_git(s: &str) -> Result { - parse(s) - } -} - /// Parse a string in Git's color configuration syntax into an -/// `anstyle::Style`. +/// [`anstyle::Style`]. pub fn parse(s: &str) -> Result { let mut style = anstyle::Style::new(); let mut num_colors = 0; @@ -94,15 +78,15 @@ pub fn parse(s: &str) -> Result { } _ => { return Err(Error::ExtraColor { - style: s.to_string(), - word: word.to_string(), + style: s.to_owned(), + word: word.to_owned(), }); } } } else { return Err(Error::UnknownWord { - style: s.to_string(), - word: word.to_string(), + style: s.to_owned(), + word: word.to_owned(), }); } } @@ -150,13 +134,23 @@ fn parse_color(word: &str) -> Result, ()> { #[non_exhaustive] pub enum Error { /// An extra color appeared after the foreground and background colors. - ExtraColor { style: String, word: String }, + ExtraColor { + /// Original style + style: String, + /// Extra color + word: String, + }, /// An unknown word appeared. - UnknownWord { style: String, word: String }, + UnknownWord { + /// Original style + style: String, + /// Unknown word + word: String, + }, } impl std::fmt::Display for Error { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::ExtraColor { style, word } => { write!( @@ -235,8 +229,8 @@ mod tests { assert_eq!( parse($s), Err($err { - style: $s.to_string(), - word: $word.to_string() + style: $s.to_owned(), + word: $word.to_owned() }) ); }; @@ -276,10 +270,4 @@ mod tests { test!("#blue" => UnknownWord "#blue"); test!("blue#123456" => UnknownWord "blue#123456"); } - - #[test] - fn test_extension_trait() { - let style = anstyle::Style::parse_git("red blue"); - assert_eq!(style.unwrap(), Red.on(Blue)); - } } diff --git a/crates/anstyle-lossy/src/lib.rs b/crates/anstyle-lossy/src/lib.rs index 6f19a5a7..f9bd6bd4 100644 --- a/crates/anstyle-lossy/src/lib.rs +++ b/crates/anstyle-lossy/src/lib.rs @@ -1,3 +1,5 @@ +//! Lossy conversion between ANSI Color Codes + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] @@ -6,6 +8,10 @@ pub mod palette; use anstyle::RgbColor as Rgb; +/// Lossily convert from any color to RGB +/// +/// As the palette for 4-bit colors is terminal/user defined, a [`palette::Palette`] must be +/// provided to match against. pub const fn color_to_rgb(color: anstyle::Color, palette: palette::Palette) -> anstyle::RgbColor { match color { anstyle::Color::Ansi(color) => ansi_to_rgb(color, palette), @@ -14,6 +20,10 @@ pub const fn color_to_rgb(color: anstyle::Color, palette: palette::Palette) -> a } } +/// Lossily convert from any color to 256-color +/// +/// As the palette for 4-bit colors is terminal/user defined, a [`palette::Palette`] must be +/// provided to match against. pub const fn color_to_xterm(color: anstyle::Color) -> anstyle::Ansi256Color { match color { anstyle::Color::Ansi(color) => anstyle::Ansi256Color::from_ansi(color), @@ -22,6 +32,10 @@ pub const fn color_to_xterm(color: anstyle::Color) -> anstyle::Ansi256Color { } } +/// Lossily convert from any color to 4-bit color +/// +/// As the palette for 4-bit colors is terminal/user defined, a [`palette::Palette`] must be +/// provided to match against. pub const fn color_to_ansi(color: anstyle::Color, palette: palette::Palette) -> anstyle::AnsiColor { match color { anstyle::Color::Ansi(color) => color, @@ -30,6 +44,10 @@ pub const fn color_to_ansi(color: anstyle::Color, palette: palette::Palette) -> } } +/// Lossily convert from 4-bit color to RGB +/// +/// As the palette for 4-bit colors is terminal/user defined, a [`palette::Palette`] must be +/// provided to match against. pub const fn ansi_to_rgb( color: anstyle::AnsiColor, palette: palette::Palette, @@ -37,6 +55,10 @@ pub const fn ansi_to_rgb( palette.rgb_from_ansi(color) } +/// Lossily convert from 256-color to RGB +/// +/// As 256-color palette is a superset of 4-bit colors and since the palette for 4-bit colors is +/// terminal/user defined, a [`palette::Palette`] must be provided to match against. pub const fn xterm_to_rgb( color: anstyle::Ansi256Color, palette: palette::Palette, @@ -47,6 +69,10 @@ pub const fn xterm_to_rgb( } } +/// Lossily convert from the 256-color palette to 4-bit color +/// +/// As the palette for 4-bit colors is terminal/user defined, a [`palette::Palette`] must be +/// provided to match against. pub const fn xterm_to_ansi( color: anstyle::Ansi256Color, palette: palette::Palette, @@ -75,6 +101,10 @@ pub const fn xterm_to_ansi( } } +/// Lossily convert an RGB value to a 4-bit color +/// +/// As the palette for 4-bit colors is terminal/user defined, a [`palette::Palette`] must be +/// provided to match against. pub const fn rgb_to_ansi( color: anstyle::RgbColor, palette: palette::Palette, @@ -82,6 +112,7 @@ pub const fn rgb_to_ansi( palette.find_match(color) } +/// Lossily convert an RGB value to the 256-color palette pub const fn rgb_to_xterm(color: anstyle::RgbColor) -> anstyle::Ansi256Color { // Skip placeholders let index = find_xterm_match(color); diff --git a/crates/anstyle-lossy/src/palette.rs b/crates/anstyle-lossy/src/palette.rs index 1a06bbc2..17922f7b 100644 --- a/crates/anstyle-lossy/src/palette.rs +++ b/crates/anstyle-lossy/src/palette.rs @@ -3,11 +3,14 @@ //! Based on [wikipedia](https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit) use anstyle::RgbColor as Rgb; +/// A color palette for rendering 4-bit [`anstyle::AnsiColor`] +#[allow(clippy::exhaustive_structs)] #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct Palette(pub RawPalette); type RawPalette = [Rgb; 16]; impl Palette { + /// Look up the [`anstyle::RgbColor`] in the palette pub const fn get(&self, color: anstyle::AnsiColor) -> Rgb { let color = anstyle::Ansi256Color::from_ansi(color); *self.get_ansi256_ref(color) @@ -45,15 +48,14 @@ impl Palette { index += 1; } - match anstyle::Ansi256Color(best_index as u8).into_ansi() { - Some(color) => color, - None => { - // Panic - #[allow(clippy::no_effect)] - ["best_index is out of bounds"][best_index]; - // Make compiler happy - anstyle::AnsiColor::Black - } + if let Some(color) = anstyle::Ansi256Color(best_index as u8).into_ansi() { + color + } else { + // Panic + #[allow(clippy::no_effect)] + ["best_index is out of bounds"][best_index]; + // Make compiler happy + anstyle::AnsiColor::Black } } } @@ -80,12 +82,15 @@ impl From for Palette { } } +/// Platform-specific default #[cfg(not(windows))] pub use VGA as DEFAULT; +/// Platform-specific default #[cfg(windows)] pub use WIN10_CONSOLE as DEFAULT; +/// Typical colors that are used when booting PCs and leaving them in text mode pub const VGA: Palette = Palette([ Rgb(0, 0, 0), Rgb(170, 0, 0), @@ -105,6 +110,7 @@ pub const VGA: Palette = Palette([ Rgb(255, 255, 255), ]); +/// Campbell theme, used as of Windows 10 version 1709. pub const WIN10_CONSOLE: Palette = Palette([ Rgb(12, 12, 12), Rgb(197, 15, 31), diff --git a/crates/anstyle-ls/src/lib.rs b/crates/anstyle-ls/src/lib.rs index c628a1d7..ff2f9eb0 100644 --- a/crates/anstyle-ls/src/lib.rs +++ b/crates/anstyle-ls/src/lib.rs @@ -12,22 +12,6 @@ #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed + Sized { - fn parse_ls(code: &str) -> Option; -} - -impl sealed::Sealed for anstyle::Style {} - -impl Ext for anstyle::Style { - fn parse_ls(code: &str) -> Option { - parse(code) - } -} - /// Parse a string in `LS_COLORS`'s color configuration syntax into an /// `ansi_term::Style`. pub fn parse(code: &str) -> Option { @@ -97,7 +81,7 @@ pub fn parse(code: &str) -> Option { (Some(5), Some(color)) => fg_color = Some(anstyle::Ansi256Color(color).into()), (Some(2), Some(red)) => match (parts.pop_front(), parts.pop_front()) { (Some(green), Some(blue)) => { - fg_color = Some(anstyle::RgbColor(red, green, blue).into()) + fg_color = Some(anstyle::RgbColor(red, green, blue).into()); } _ => { break; @@ -120,7 +104,7 @@ pub fn parse(code: &str) -> Option { (Some(5), Some(color)) => bg_color = Some(anstyle::Ansi256Color(color).into()), (Some(2), Some(red)) => match (parts.pop_front(), parts.pop_front()) { (Some(green), Some(blue)) => { - bg_color = Some(anstyle::RgbColor(red, green, blue).into()) + bg_color = Some(anstyle::RgbColor(red, green, blue).into()); } _ => { break; @@ -133,11 +117,11 @@ pub fn parse(code: &str) -> Option { 49 => bg_color = None, 58 => match (parts.pop_front(), parts.pop_front()) { (Some(5), Some(color)) => { - underline_color = Some(anstyle::Ansi256Color(color).into()) + underline_color = Some(anstyle::Ansi256Color(color).into()); } (Some(2), Some(red)) => match (parts.pop_front(), parts.pop_front()) { (Some(green), Some(blue)) => { - underline_color = Some(anstyle::RgbColor(red, green, blue).into()) + underline_color = Some(anstyle::RgbColor(red, green, blue).into()); } _ => { break; @@ -185,7 +169,7 @@ mod tests { #[track_caller] fn assert_style(code: &str, expected: impl Into) { - let actual = anstyle::Style::parse_ls(code).unwrap(); + let actual = parse(code).unwrap(); let expected = expected.into(); assert_eq!(actual, expected); } @@ -210,9 +194,9 @@ mod tests { #[test] fn parse_reject() { - assert_eq!(None, anstyle::Style::parse_ls("a")); - assert_eq!(None, anstyle::Style::parse_ls("1;")); - assert_eq!(None, anstyle::Style::parse_ls("33; 42")); + assert_eq!(None, parse("a")); + assert_eq!(None, parse("1;")); + assert_eq!(None, parse("33; 42")); } #[test] diff --git a/crates/anstyle-owo-colors/README.md b/crates/anstyle-owo-colors/README.md index 2c71fbe2..e59e6ae5 100644 --- a/crates/anstyle-owo-colors/README.md +++ b/crates/anstyle-owo-colors/README.md @@ -1,6 +1,6 @@ # anstyle-owo-colors -> Convert from color styling types to [owo-colors](https://lib.rs/owo-colors) color types +> Convert between [owo-colors](https://lib.rs/owo-colors) and generic styling types [![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation] ![License](https://img.shields.io/crates/l/anstyle-owo-colors.svg) diff --git a/crates/anstyle-owo-colors/src/lib.rs b/crates/anstyle-owo-colors/src/lib.rs index a3ffed92..e080891a 100644 --- a/crates/anstyle-owo-colors/src/lib.rs +++ b/crates/anstyle-owo-colors/src/lib.rs @@ -1,23 +1,10 @@ +//! Convert between [owo-colors](https://lib.rs/owo-colors) and generic styling types + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed { - fn to_owo(self) -> owo_colors::Style; -} - -impl sealed::Sealed for anstyle::Style {} - -impl Ext for anstyle::Style { - fn to_owo(self) -> owo_colors::Style { - to_owo_style(self) - } -} - +/// Adapt generic styling to [`owo_colors`] pub fn to_owo_style(style: anstyle::Style) -> owo_colors::Style { let fg = style.get_fg_color().map(to_owo_colors); let bg = style.get_bg_color().map(to_owo_colors); @@ -57,6 +44,7 @@ pub fn to_owo_style(style: anstyle::Style) -> owo_colors::Style { style } +/// Adapt generic colors to [`owo_colors`] pub fn to_owo_colors(color: anstyle::Color) -> owo_colors::DynColors { match color { anstyle::Color::Ansi(ansi) => owo_colors::DynColors::Ansi(ansi_to_owo_colors_color(ansi)), diff --git a/crates/anstyle-parse/benches/parse.rs b/crates/anstyle-parse/benches/parse.rs index 38469671..3cb44580 100644 --- a/crates/anstyle-parse/benches/parse.rs +++ b/crates/anstyle-parse/benches/parse.rs @@ -1,6 +1,10 @@ +#![allow(missing_docs)] use std::hint::black_box; -use anstyle_parse::*; +use anstyle_parse::DefaultCharAccumulator; +use anstyle_parse::Params; +use anstyle_parse::Parser; +use anstyle_parse::Perform; #[divan::bench(args = DATA)] fn advance(data: &Data) { @@ -35,7 +39,7 @@ fn state_change(data: &Data) { } #[divan::bench(args = DATA)] -fn state_change_strip_str(bencher: divan::Bencher, data: &Data) { +fn state_change_strip_str(bencher: divan::Bencher<'_, '_>, data: &Data) { if let Ok(content) = std::str::from_utf8(data.content()) { bencher .with_inputs(|| content) @@ -43,7 +47,7 @@ fn state_change_strip_str(bencher: divan::Bencher, data: &Data) { let stripped = strip_str(content); black_box(stripped) - }) + }); } } @@ -141,6 +145,7 @@ fn strip_str(content: &str) -> String { bytes = next; } + #[allow(clippy::unwrap_used)] String::from_utf8(stripped).unwrap() } @@ -162,14 +167,14 @@ const DATA: &[Data] = &[ ]; #[derive(Debug)] -pub struct Data(&'static str, &'static [u8]); +struct Data(&'static str, &'static [u8]); impl Data { - pub const fn name(&self) -> &'static str { + const fn name(&self) -> &'static str { self.0 } - pub const fn content(&self) -> &'static [u8] { + const fn content(&self) -> &'static [u8] { self.1 } } diff --git a/crates/anstyle-parse/src/lib.rs b/crates/anstyle-parse/src/lib.rs index a515c5c3..76c6cd6b 100644 --- a/crates/anstyle-parse/src/lib.rs +++ b/crates/anstyle-parse/src/lib.rs @@ -28,6 +28,7 @@ //! all states. //! //! [Paul Williams' ANSI parser state machine]: https://vt100.net/emu/dec_ansi_parser +#![allow(missing_docs)] #![cfg_attr(not(test), no_std)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] @@ -56,6 +57,7 @@ const MAX_OSC_PARAMS: usize = 16; const MAX_OSC_RAW: usize = 1024; /// Parser for raw _VTE_ protocol which delegates actions to a [`Perform`] +#[allow(unused_qualifications)] #[derive(Default, Clone, Debug, PartialEq, Eq)] pub struct Parser { state: State, @@ -165,9 +167,9 @@ where } } - /// Separate method for osc_dispatch that borrows self as read-only + /// Separate method for `osc_dispatch` that borrows self as read-only /// - /// The aliasing is needed here for multiple slices into self.osc_raw + /// The aliasing is needed here for multiple slices into `self.osc_raw` #[inline] fn osc_dispatch(&self, performer: &mut P, byte: u8) { let mut slices: [MaybeUninit<&[u8]>; MAX_OSC_PARAMS] = @@ -325,12 +327,14 @@ pub trait CharAccumulator: Default { fn add(&mut self, byte: u8) -> Option; } +/// Most flexible [`CharAccumulator`] for [`Parser`] based on active features #[cfg(feature = "utf8")] pub type DefaultCharAccumulator = Utf8Parser; #[cfg(not(feature = "utf8"))] pub type DefaultCharAccumulator = AsciiParser; /// Only allow parsing 7-bit ASCII +#[allow(clippy::exhaustive_structs)] #[derive(Default, Clone, Debug, PartialEq, Eq)] pub struct AsciiParser; diff --git a/crates/anstyle-parse/src/state/codegen.rs b/crates/anstyle-parse/src/state/codegen.rs index 8c2bf550..58a2507b 100644 --- a/crates/anstyle-parse/src/state/codegen.rs +++ b/crates/anstyle-parse/src/state/codegen.rs @@ -52,7 +52,7 @@ pub(crate) const STATE_CHANGES: [[u8; 256]; 16] = ["# /// This is the state change table. It's indexed first by current state and then by the next /// character in the pty stream. -pub static STATE_CHANGES: [[u8; 256]; 16] = state_changes(); +pub(crate) static STATE_CHANGES: [[u8; 256]; 16] = state_changes(); generate_state_changes!(state_changes, { Anywhere { 0x18 => (Ground, Execute), diff --git a/crates/anstyle-parse/src/state/definitions.rs b/crates/anstyle-parse/src/state/definitions.rs index c4e76735..4b03a9ad 100644 --- a/crates/anstyle-parse/src/state/definitions.rs +++ b/crates/anstyle-parse/src/state/definitions.rs @@ -1,3 +1,5 @@ +#![allow(clippy::exhaustive_enums)] + use core::mem; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -110,7 +112,7 @@ const ACTIONS: [Action; 16] = [ /// /// Bad things will happen if those invariants are violated. #[inline(always)] -pub const fn unpack(delta: u8) -> (State, Action) { +pub(crate) const fn unpack(delta: u8) -> (State, Action) { unsafe { ( // State is stored in bottom 4 bits @@ -123,7 +125,7 @@ pub const fn unpack(delta: u8) -> (State, Action) { #[inline(always)] #[cfg(test)] -pub const fn pack(state: State, action: Action) -> u8 { +pub(crate) const fn pack(state: State, action: Action) -> u8 { (action as u8) << 4 | state as u8 } diff --git a/crates/anstyle-parse/src/state/mod.rs b/crates/anstyle-parse/src/state/mod.rs index 91942059..a1d86918 100644 --- a/crates/anstyle-parse/src/state/mod.rs +++ b/crates/anstyle-parse/src/state/mod.rs @@ -1,3 +1,5 @@ +//! ANSI escape code parsing state machine + #[cfg(test)] mod codegen; mod definitions; diff --git a/crates/anstyle-query/examples/query.rs b/crates/anstyle-query/examples/query.rs index 2e5f0219..e5d66205 100644 --- a/crates/anstyle-query/examples/query.rs +++ b/crates/anstyle-query/examples/query.rs @@ -1,3 +1,5 @@ +//! Report a terminal's capabilities + fn main() { println!("clicolor: {:?}", anstyle_query::clicolor()); println!("clicolor_force: {}", anstyle_query::clicolor_force()); diff --git a/crates/anstyle-query/src/lib.rs b/crates/anstyle-query/src/lib.rs index a331050e..6b44d674 100644 --- a/crates/anstyle-query/src/lib.rs +++ b/crates/anstyle-query/src/lib.rs @@ -1,3 +1,5 @@ +//! Low level terminal capability lookups + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] diff --git a/crates/anstyle-query/src/windows.rs b/crates/anstyle-query/src/windows.rs index a8ce404a..ba4971aa 100644 --- a/crates/anstyle-query/src/windows.rs +++ b/crates/anstyle-query/src/windows.rs @@ -64,7 +64,7 @@ mod windows_console { } } -/// Enable ANSI escape codes (ENABLE_VIRTUAL_TERMINAL_PROCESSING) +/// Enable ANSI escape codes ([`ENABLE_VIRTUAL_TERMINAL_PROCESSING`](https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences)) /// /// For non-windows systems, returns `None` pub fn enable_ansi_colors() -> Option { diff --git a/crates/anstyle-roff/src/lib.rs b/crates/anstyle-roff/src/lib.rs index 73c92d99..7a43ae7d 100644 --- a/crates/anstyle-roff/src/lib.rs +++ b/crates/anstyle-roff/src/lib.rs @@ -15,14 +15,14 @@ use styled_str::StyledStr; /// Static Strings defining ROFF Control Requests mod control_requests { /// Control to Create a Color definition - pub const CREATE_COLOR: &str = "defcolor"; + pub(crate) const CREATE_COLOR: &str = "defcolor"; /// Roff control request to set background color (fill color) - pub const BACKGROUND: &str = "fcolor"; + pub(crate) const BACKGROUND: &str = "fcolor"; /// Roff control request to set foreground color (glyph color) - pub const FOREGROUND: &str = "gcolor"; + pub(crate) const FOREGROUND: &str = "gcolor"; } -/// Generate A RoffStyle from Style +/// Generate a [`Roff`] from ANSI escape codes /// /// ```rust /// let text = "\u{1b}[44;31mtest\u{1b}[0m"; @@ -47,7 +47,7 @@ pub fn to_roff(styled_text: &str) -> Roff { doc } -fn set_effects_and_text(styled: &StyledStr, doc: &mut Roff) { +fn set_effects_and_text(styled: &StyledStr<'_>, doc: &mut Roff) { // Roff (the crate) only supports these inline commands // - Bold // - Italic @@ -73,7 +73,7 @@ fn has_bright_fg(style: &Style) -> bool { .unwrap_or(false) } -/// Check if Color is an AnsiColor::Bright* variant +/// Check if [`Color`] is an [`AnsiColor::Bright*`][AnsiColor] variant fn is_bright(fg_color: &Color) -> bool { if let Color::Ansi(color) = fg_color { matches!( @@ -94,7 +94,7 @@ fn is_bright(fg_color: &Color) -> bool { type ColorSet<'a> = (&'a Option, &'a Option); -fn set_color(colors: ColorSet, doc: &mut Roff) { +fn set_color(colors: ColorSet<'_>, doc: &mut Roff) { add_color_to_roff(doc, control_requests::FOREGROUND, colors.0); add_color_to_roff(doc, control_requests::BACKGROUND, colors.1); } @@ -120,7 +120,7 @@ fn add_color_to_roff(doc: &mut Roff, control_request: &str, color: &Option { // TODO: get rid of "default" hardcoded str? @@ -147,7 +147,7 @@ fn to_hex(rgb: &RgbColor) -> String { } /// Map Color and Bright Variants to Roff Color styles -fn ansi_color_to_roff(color: &anstyle::AnsiColor) -> &'static str { +fn ansi_color_to_roff(color: &AnsiColor) -> &'static str { match color { AnsiColor::Black | AnsiColor::BrightBlack => "black", AnsiColor::Red | AnsiColor::BrightRed => "red", diff --git a/crates/anstyle-roff/src/styled_str.rs b/crates/anstyle-roff/src/styled_str.rs index 59ffb67e..cf5030d8 100644 --- a/crates/anstyle-roff/src/styled_str.rs +++ b/crates/anstyle-roff/src/styled_str.rs @@ -3,8 +3,8 @@ use anstyle::{AnsiColor, Color as AColor, Effects, Style}; use cansi::{v3::CategorisedSlice, Color, Intensity}; -/// Produce a stream of StyledStr from text that contains ansi escape sequences -pub(crate) fn styled_stream(text: &str) -> impl Iterator { +/// Produce a stream of [`StyledStr`] from text that contains ansi escape sequences +pub(crate) fn styled_stream(text: &str) -> impl Iterator> { let categorized = cansi::v3::categorise_text(text); categorized.into_iter().map(|x| x.into()) } @@ -12,8 +12,8 @@ pub(crate) fn styled_stream(text: &str) -> impl Iterator { /// Represents a Section of text, along with the desired styling for it #[derive(Debug, Default, Clone, Copy)] pub(crate) struct StyledStr<'text> { - pub text: &'text str, - pub style: Style, + pub(crate) text: &'text str, + pub(crate) style: Style, } impl<'text> From> for StyledStr<'text> { @@ -33,7 +33,7 @@ impl<'text> From> for StyledStr<'text> { } } -fn create_effects(category: &CategorisedSlice) -> Effects { +fn create_effects(category: &CategorisedSlice<'_>) -> Effects { Effects::new() .set(Effects::ITALIC, category.italic.unwrap_or(false)) .set(Effects::BLINK, category.blink.unwrap_or(false)) @@ -83,14 +83,16 @@ mod tests { use super::*; - /// Creates a CategorisedSlice for Testing + /// Creates a [`CategorisedSlice`] for Testing /// - /// styled_str!( Text, [Color:COLOR_SET] [Intensity:INTENSITY_SET] [Effects:EFFECTS_SET]) + /// ```rust + /// styled_str!(Text, [Color:COLOR_SET] [Intensity:INTENSITY_SET] [Effects:EFFECTS_SET]) + /// ``` /// /// Where: - /// COLOR_SET={fg|bg}: - /// INTENSITY_SET= - /// EFFECTS_SET = {"underline"|"italic"|"blink"|"reversed"|"strikethrough"|"hidden"};+ + /// `COLOR_SET={fg|bg}:` + /// `INTENSITY_SET=` + /// `EFFECTS_SET={"underline"|"italic"|"blink"|"reversed"|"strikethrough"|"hidden"};+` macro_rules! styled_str { ($text: literal, $(Color:$color_key:literal:$color_val:expr;)* $(Intensity:$intensity:expr;)? $(Effects:$($key:literal;)+)? ) => { { @@ -137,14 +139,14 @@ mod tests { #[test] fn from_categorized_underlined() { let categorised = styled_str!("Hello", Effects:"underline";); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str.style.get_effects().contains(Effects::UNDERLINE)); } #[test] fn from_categorized_underlined_striketrhough() { let categorised = styled_str!("Hello", Effects:"underline";"strikethrough";); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str.style.get_effects().contains(Effects::UNDERLINE)); assert!(styled_str .style @@ -155,21 +157,21 @@ mod tests { #[test] fn from_categorized_blink() { let categorised = styled_str!("Hello", Effects:"blink";); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str.style.get_effects().contains(Effects::BLINK)); } #[test] fn from_categorized_reversed() { let categorised = styled_str!("Hello", Effects:"reversed";); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str.style.get_effects().contains(Effects::INVERT)); } #[test] fn from_categorized_strikthrough() { let categorised = styled_str!("Hello", Effects:"strikethrough";); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str .style .get_effects() @@ -179,14 +181,14 @@ mod tests { #[test] fn from_categorized_hidden() { let categorised = styled_str!("Hello", Effects:"hidden";); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str.style.get_effects().contains(Effects::HIDDEN)); } #[test] fn from_categorized_bg() { let categorised = styled_str!("Hello", Color:"bg":Color::Blue;); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(matches!( styled_str.style.get_bg_color(), Some(AColor::Ansi(AnsiColor::Blue)) @@ -196,7 +198,7 @@ mod tests { #[test] fn from_categorized_fg() { let categorised = styled_str!("Hello", Color:"fg":Color::Blue;); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(matches!( styled_str.style.get_fg_color(), Some(AColor::Ansi(AnsiColor::Blue)) @@ -206,14 +208,14 @@ mod tests { #[test] fn from_categorized_bold() { let categorised = styled_str!("Hello", Intensity:Intensity::Bold;); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str.style.get_effects().contains(Effects::BOLD)); } #[test] fn from_categorized_faint() { let categorised = styled_str!("Hello", Intensity:Intensity::Faint;); - let styled_str: StyledStr = categorised.into(); + let styled_str: StyledStr<'_> = categorised.into(); assert!(styled_str.style.get_effects().contains(Effects::DIMMED)); } } diff --git a/crates/anstyle-svg/src/lib.rs b/crates/anstyle-svg/src/lib.rs index d0b5a83f..edf00a7a 100644 --- a/crates/anstyle-svg/src/lib.rs +++ b/crates/anstyle-svg/src/lib.rs @@ -33,6 +33,7 @@ pub struct Term { } impl Term { + /// Default terminal settings pub const fn new() -> Self { Self { palette: VGA, @@ -80,8 +81,12 @@ impl Term { /// **Note:** Lines are not wrapped. This is intentional as this attempts to convey the exact /// output with escape codes translated to SVG elements. pub fn render_svg(&self, ansi: &str) -> String { + use std::fmt::Write as _; use unicode_width::UnicodeWidthStr as _; + const FG: &str = "fg"; + const BG: &str = "bg"; + let mut styled = anstream::adapter::WinconBytes::new(); let mut styled = styled.extract_next(ansi.as_bytes()).collect::>(); let mut effects_in_use = anstyle::Effects::new(); @@ -97,9 +102,7 @@ impl Term { } let styled_lines = split_lines(&styled); - const FG: &str = "fg"; let fg_color = rgb_value(self.fg_color, self.palette); - const BG: &str = "bg"; let bg_color = rgb_value(self.bg_color, self.palette); let font_family = self.font_family; @@ -113,7 +116,6 @@ impl Term { let width_px = (max_width as f64 * 8.4).ceil() as usize; let width_px = std::cmp::max(width_px, self.min_width_px) + self.padding_px * 2; - use std::fmt::Write as _; let mut buffer = String::new(); writeln!( &mut buffer, @@ -263,6 +265,7 @@ const FG_COLOR: anstyle::Color = anstyle::Color::Ansi(anstyle::AnsiColor::White) const BG_COLOR: anstyle::Color = anstyle::Color::Ansi(anstyle::AnsiColor::Black); fn write_fg_span(buffer: &mut String, style: &anstyle::Style, fragment: &str) { + use std::fmt::Write as _; let fg_color = style.get_fg_color().map(|c| color_name(FG_PREFIX, c)); let underline_color = style .get_underline_color() @@ -319,7 +322,6 @@ fn write_fg_span(buffer: &mut String, style: &anstyle::Style, fragment: &str) { classes.push("hidden"); } - use std::fmt::Write as _; write!(buffer, r#" String { +fn rgb_value(color: anstyle::Color, palette: Palette) -> String { let color = anstyle_lossy::color_to_rgb(color, palette); let anstyle::RgbColor(r, g, b) = color; format!("#{r:02X}{g:02X}{b:02X}") @@ -411,7 +413,7 @@ fn color_name(prefix: &str, color: anstyle::Color) -> String { fn color_styles( styled: &[(anstyle::Style, String)], - palette: anstyle_lossy::palette::Palette, + palette: Palette, ) -> impl Iterator { let mut colors = std::collections::BTreeMap::new(); for (style, _) in styled { diff --git a/crates/anstyle-syntect/README.md b/crates/anstyle-syntect/README.md index 81d68efe..5bc2bd02 100644 --- a/crates/anstyle-syntect/README.md +++ b/crates/anstyle-syntect/README.md @@ -1,6 +1,6 @@ # anstyle-syntect -> Convert from color styling types to [`ansi_term`](https://lib.rs/syntect) color types +> Convert between [`syntect`](https://lib.rs/syntect) highlighting and generic styling types [![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation] ![License](https://img.shields.io/crates/l/anstyle-syntect.svg) diff --git a/crates/anstyle-syntect/src/lib.rs b/crates/anstyle-syntect/src/lib.rs index fb32a1ea..d3baae75 100644 --- a/crates/anstyle-syntect/src/lib.rs +++ b/crates/anstyle-syntect/src/lib.rs @@ -1,23 +1,11 @@ +//! Convert between [`syntect`](https://lib.rs/syntect) highlighting and +//! [generic styling types][anstyle::Style] + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed { - fn syntect_to_anstyle(self) -> anstyle::Style; -} - -impl sealed::Sealed for syntect::highlighting::Style {} - -impl Ext for syntect::highlighting::Style { - fn syntect_to_anstyle(self) -> anstyle::Style { - to_anstyle(self) - } -} - +/// Convert highlighting style to general style pub fn to_anstyle(style: syntect::highlighting::Style) -> anstyle::Style { anstyle::Style::new() .fg_color(Some(to_anstyle_color(style.foreground))) @@ -25,10 +13,12 @@ pub fn to_anstyle(style: syntect::highlighting::Style) -> anstyle::Style { .effects(to_anstyle_effects(style.font_style)) } +/// Convert highlighting color to general color pub fn to_anstyle_color(color: syntect::highlighting::Color) -> anstyle::Color { anstyle::RgbColor(color.r, color.g, color.b).into() } +/// Convert highlighting style to general effects pub fn to_anstyle_effects(style: syntect::highlighting::FontStyle) -> anstyle::Effects { let mut effects = anstyle::Effects::new(); diff --git a/crates/anstyle-termcolor/README.md b/crates/anstyle-termcolor/README.md index 2f1b7404..682b7ae9 100644 --- a/crates/anstyle-termcolor/README.md +++ b/crates/anstyle-termcolor/README.md @@ -1,6 +1,6 @@ # anstyle-termcolor -> Convert from color styling types to [termcolor](https://lib.rs/termcolor) color types +> Convert between [termcolor](https://lib.rs/termcolor) and generic styling types [![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation] ![License](https://img.shields.io/crates/l/anstyle-termcolor.svg) diff --git a/crates/anstyle-termcolor/src/lib.rs b/crates/anstyle-termcolor/src/lib.rs index 7c676c1b..baa63b51 100644 --- a/crates/anstyle-termcolor/src/lib.rs +++ b/crates/anstyle-termcolor/src/lib.rs @@ -1,23 +1,10 @@ +//! Convert between [termcolor](https://lib.rs/termcolor) and [generic styling types][anstyle] + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed { - fn to_termcolor(self) -> termcolor::ColorSpec; -} - -impl sealed::Sealed for anstyle::Style {} - -impl Ext for anstyle::Style { - fn to_termcolor(self) -> termcolor::ColorSpec { - to_termcolor_spec(self) - } -} - +/// Adapt generic styling to [`termcolor`] pub fn to_termcolor_spec(style: anstyle::Style) -> termcolor::ColorSpec { let fg = style.get_fg_color().map(to_termcolor_color); let bg = style.get_bg_color().map(to_termcolor_color); @@ -33,6 +20,7 @@ pub fn to_termcolor_spec(style: anstyle::Style) -> termcolor::ColorSpec { style } +/// Adapt generic colors to [`termcolor`] pub fn to_termcolor_color(color: anstyle::Color) -> termcolor::Color { match color { anstyle::Color::Ansi(ansi) => ansi_to_termcolor_color(ansi), diff --git a/crates/anstyle-wincon/examples/dump-wincon.rs b/crates/anstyle-wincon/examples/dump-wincon.rs index 954ee47b..2e3ab564 100644 --- a/crates/anstyle-wincon/examples/dump-wincon.rs +++ b/crates/anstyle-wincon/examples/dump-wincon.rs @@ -1,3 +1,5 @@ +//! Write colored text using wincon API calls + use anstyle_wincon::WinconStream as _; fn main() -> Result<(), lexopt::Error> { @@ -84,7 +86,7 @@ enum Layer { impl Args { fn parse() -> Result { - use lexopt::prelude::*; + use lexopt::prelude::{Long, ValueExt}; let mut res = Args::default(); diff --git a/crates/anstyle-wincon/examples/set-wincon.rs b/crates/anstyle-wincon/examples/set-wincon.rs index 6febb0ae..19ef8440 100644 --- a/crates/anstyle-wincon/examples/set-wincon.rs +++ b/crates/anstyle-wincon/examples/set-wincon.rs @@ -1,3 +1,5 @@ +//! Interactively manipulate wincon colors + #![cfg_attr(not(windows), allow(dead_code))] #[cfg(not(windows))] @@ -31,7 +33,7 @@ struct Args { impl Args { fn parse() -> Result { - use lexopt::prelude::*; + use lexopt::prelude::{Long, ValueExt}; let mut res = Args::default(); diff --git a/crates/anstyle-wincon/src/stream.rs b/crates/anstyle-wincon/src/stream.rs index 9f101080..cd6f18f6 100644 --- a/crates/anstyle-wincon/src/stream.rs +++ b/crates/anstyle-wincon/src/stream.rs @@ -101,9 +101,7 @@ impl WinconStream for std::io::Stderr { #[cfg(not(windows))] mod platform { - use super::*; - - impl WinconStream for std::io::StdoutLock<'_> { + impl super::WinconStream for std::io::StdoutLock<'_> { fn write_colored( &mut self, fg: Option, @@ -114,7 +112,7 @@ mod platform { } } - impl WinconStream for std::io::StderrLock<'_> { + impl super::WinconStream for std::io::StderrLock<'_> { fn write_colored( &mut self, fg: Option, @@ -128,9 +126,7 @@ mod platform { #[cfg(windows)] mod platform { - use super::*; - - impl WinconStream for std::io::StdoutLock<'_> { + impl super::WinconStream for std::io::StdoutLock<'_> { fn write_colored( &mut self, fg: Option, @@ -142,7 +138,7 @@ mod platform { } } - impl WinconStream for std::io::StderrLock<'_> { + impl super::WinconStream for std::io::StderrLock<'_> { fn write_colored( &mut self, fg: Option, diff --git a/crates/anstyle-yansi/README.md b/crates/anstyle-yansi/README.md index 436e38ff..b5cebea7 100644 --- a/crates/anstyle-yansi/README.md +++ b/crates/anstyle-yansi/README.md @@ -1,6 +1,6 @@ # anstyle-yansi -> Convert from color styling types to [yansi](https://lib.rs/yansi) color types +> Convert between [yansi](https://lib.rs/yansi) and generic styling types [![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation] ![License](https://img.shields.io/crates/l/anstyle-yansi.svg) diff --git a/crates/anstyle-yansi/src/lib.rs b/crates/anstyle-yansi/src/lib.rs index 5445665f..84e8cc7f 100644 --- a/crates/anstyle-yansi/src/lib.rs +++ b/crates/anstyle-yansi/src/lib.rs @@ -1,23 +1,10 @@ +//! Convert between [yansi](https://lib.rs/yansi) and generic styling types + #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] -mod sealed { - pub(crate) trait Sealed {} -} - -trait Ext: sealed::Sealed { - fn to_yansi(self) -> yansi::Style; -} - -impl sealed::Sealed for anstyle::Style {} - -impl Ext for anstyle::Style { - fn to_yansi(self) -> yansi::Style { - to_yansi_style(self) - } -} - +/// Adapt generic styling to [`yansi`] pub fn to_yansi_style(style: anstyle::Style) -> yansi::Style { let (fg, fg_bold) = style .get_fg_color() @@ -57,6 +44,7 @@ pub fn to_yansi_style(style: anstyle::Style) -> yansi::Style { style } +/// Adapt generic color to [`yansi`] pub fn to_yansi_color(color: anstyle::Color) -> yansi::Color { to_yansi_color_with_bold(color).0 } diff --git a/crates/anstyle/examples/dump-style.rs b/crates/anstyle/examples/dump-style.rs index 2a5a37d1..9b83abd9 100644 --- a/crates/anstyle/examples/dump-style.rs +++ b/crates/anstyle/examples/dump-style.rs @@ -1,3 +1,5 @@ +//! Write ANSI escape code colored text + use std::io::Write; fn main() -> Result<(), lexopt::Error> { @@ -6,7 +8,9 @@ fn main() -> Result<(), lexopt::Error> { let mut stdout = stdout.lock(); for fixed in 0..16 { - let color = anstyle::Ansi256Color(fixed).into_ansi().unwrap(); + let color = anstyle::Ansi256Color(fixed) + .into_ansi() + .expect("4-bit range used"); let style = style(color, args.layer, args.effects); let _ = print_number(&mut stdout, fixed, style); if fixed == 7 || fixed == 15 { @@ -74,7 +78,7 @@ enum Layer { impl Args { fn parse() -> Result { - use lexopt::prelude::*; + use lexopt::prelude::{Long, ValueExt}; let mut res = Args::default(); diff --git a/crates/anstyle/src/color.rs b/crates/anstyle/src/color.rs index 797d4b54..a9aafb5a 100644 --- a/crates/anstyle/src/color.rs +++ b/crates/anstyle/src/color.rs @@ -1,8 +1,18 @@ /// Any ANSI color code scheme +#[allow(clippy::exhaustive_enums)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Color { + /// Available 4-bit ANSI color palette codes + /// + /// The user's terminal defines the meaning of the each palette code. Ansi(AnsiColor), + /// 256 (8-bit) color support + /// + /// - `0..16` are [`AnsiColor`] palette codes + /// - `0..232` map to [`RgbColor`] color values + /// - `232..` map to [`RgbColor`] gray-scale values Ansi256(Ansi256Color), + /// 24-bit ANSI RGB color codes Rgb(RgbColor), } @@ -23,7 +33,7 @@ impl Color { /// Render the ANSI code for a foreground color #[inline] - pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_fg(self) -> impl core::fmt::Display + Copy { match self { Self::Ansi(color) => color.as_fg_buffer(), Self::Ansi256(color) => color.as_fg_buffer(), @@ -44,7 +54,7 @@ impl Color { /// Render the ANSI code for a background color #[inline] - pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_bg(self) -> impl core::fmt::Display + Copy { match self { Self::Ansi(color) => color.as_bg_buffer(), Self::Ansi256(color) => color.as_bg_buffer(), @@ -64,7 +74,7 @@ impl Color { } #[inline] - pub(crate) fn render_underline(self) -> impl core::fmt::Display + Copy + Clone { + pub(crate) fn render_underline(self) -> impl core::fmt::Display + Copy { match self { Self::Ansi(color) => color.as_underline_buffer(), Self::Ansi256(color) => color.as_underline_buffer(), @@ -122,6 +132,7 @@ impl From<(u8, u8, u8)> for Color { /// Available 4-bit ANSI color palette codes /// /// The user's terminal defines the meaning of the each palette code. +#[allow(clippy::exhaustive_enums)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum AnsiColor { @@ -191,7 +202,7 @@ impl AnsiColor { /// Render the ANSI code for a foreground color #[inline] - pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_fg(self) -> impl core::fmt::Display + Copy { NullFormatter(self.as_fg_str()) } @@ -224,7 +235,7 @@ impl AnsiColor { /// Render the ANSI code for a background color #[inline] - pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_bg(self) -> impl core::fmt::Display + Copy { NullFormatter(self.as_bg_str()) } @@ -335,6 +346,7 @@ impl AnsiColor { /// - `0..16` are [`AnsiColor`] palette codes /// - `0..232` map to [`RgbColor`] color values /// - `232..` map to [`RgbColor`] gray-scale values +#[allow(clippy::exhaustive_structs)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct Ansi256Color(pub u8); @@ -354,11 +366,13 @@ impl Ansi256Color { crate::Style::new().fg_color(Some(Color::Ansi256(self))) } + /// Get the raw value #[inline] pub const fn index(self) -> u8 { self.0 } + /// Convert to [`AnsiColor`] when there is a 1:1 mapping #[inline] pub const fn into_ansi(self) -> Option { match self.index() { @@ -382,6 +396,7 @@ impl Ansi256Color { } } + /// Losslessly convert from [`AnsiColor`] #[inline] pub const fn from_ansi(color: AnsiColor) -> Self { match color { @@ -406,7 +421,7 @@ impl Ansi256Color { /// Render the ANSI code for a foreground color #[inline] - pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_fg(self) -> impl core::fmt::Display + Copy { self.as_fg_buffer() } @@ -420,7 +435,7 @@ impl Ansi256Color { /// Render the ANSI code for a background color #[inline] - pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_bg(self) -> impl core::fmt::Display + Copy { self.as_bg_buffer() } @@ -456,6 +471,7 @@ impl From for Ansi256Color { } /// 24-bit ANSI RGB color codes +#[allow(clippy::exhaustive_structs)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RgbColor(pub u8, pub u8, pub u8); @@ -474,16 +490,19 @@ impl RgbColor { crate::Style::new().fg_color(Some(Color::Rgb(self))) } + /// Red #[inline] pub const fn r(self) -> u8 { self.0 } + /// Green #[inline] pub const fn g(self) -> u8 { self.1 } + /// Blue #[inline] pub const fn b(self) -> u8 { self.2 @@ -491,7 +510,7 @@ impl RgbColor { /// Render the ANSI code for a foreground color #[inline] - pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_fg(self) -> impl core::fmt::Display + Copy { self.as_fg_buffer() } @@ -509,7 +528,7 @@ impl RgbColor { /// Render the ANSI code for a background color #[inline] - pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_bg(self) -> impl core::fmt::Display + Copy { self.as_bg_buffer() } @@ -592,7 +611,10 @@ impl DisplayBuffer { #[inline] fn as_str(&self) -> &str { // SAFETY: Only `&str` can be written to the buffer - unsafe { core::str::from_utf8_unchecked(&self.buffer[0..self.len]) } + #[allow(unsafe_code)] + unsafe { + core::str::from_utf8_unchecked(&self.buffer[0..self.len]) + } } #[inline] diff --git a/crates/anstyle/src/effect.rs b/crates/anstyle/src/effect.rs index f782776c..1a80fa3e 100644 --- a/crates/anstyle/src/effect.rs +++ b/crates/anstyle/src/effect.rs @@ -9,21 +9,30 @@ pub struct Effects(u16); impl Effects { + /// No [`Effects`] applied const PLAIN: Self = Effects(0); + #[allow(missing_docs)] pub const BOLD: Self = Effects(1 << 0); + #[allow(missing_docs)] pub const DIMMED: Self = Effects(1 << 1); /// Not widely supported. Sometimes treated as inverse or blink pub const ITALIC: Self = Effects(1 << 2); /// Style extensions exist for Kitty, VTE, mintty and iTerm2. pub const UNDERLINE: Self = Effects(1 << 3); + #[allow(missing_docs)] pub const DOUBLE_UNDERLINE: Self = Effects(1 << 4); + #[allow(missing_docs)] pub const CURLY_UNDERLINE: Self = Effects(1 << 5); + #[allow(missing_docs)] pub const DOTTED_UNDERLINE: Self = Effects(1 << 6); + #[allow(missing_docs)] pub const DASHED_UNDERLINE: Self = Effects(1 << 7); + #[allow(missing_docs)] pub const BLINK: Self = Effects(1 << 8); /// Swap foreground and background colors; inconsistent emulation pub const INVERT: Self = Effects(1 << 9); + #[allow(missing_docs)] pub const HIDDEN: Self = Effects(1 << 10); /// Characters legible but marked as if for deletion. Not supported in Terminal.app pub const STRIKETHROUGH: Self = Effects(1 << 11); @@ -156,7 +165,7 @@ impl Effects { /// Render the ANSI code #[inline] - pub fn render(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render(self) -> impl core::fmt::Display + Copy { EffectsDisplay(self) } @@ -321,6 +330,7 @@ impl core::fmt::Display for EffectsDisplay { } } +/// Enumerate each enabled value in [`Effects`] #[derive(Clone, Debug, PartialEq, Eq)] pub struct EffectIter { index: usize, diff --git a/crates/anstyle/src/lib.rs b/crates/anstyle/src/lib.rs index 44498c35..e1d4946d 100644 --- a/crates/anstyle/src/lib.rs +++ b/crates/anstyle/src/lib.rs @@ -25,11 +25,12 @@ //! //! User-styling parsers: //! - [anstyle-git](https://docs.rs/anstyle-git): Parse Git style descriptions -//! - [anstyle-ls](https://docs.rs/anstyle-ls): Parse LS_COLORS style descriptions +//! - [anstyle-ls](https://docs.rs/anstyle-ls): Parse `LS_COLORS` style descriptions //! //! Convert to other formats //! - [anstream](https://docs.rs/anstream): A simple cross platform library for writing colored text to a terminal //! - [anstyle-roff](https://docs.rs/anstyle-roff): For converting to ROFF +//! - [anstyle-syntect](https://docs.rs/anstyle-syntect): For working with syntax highlighting //! //! Utilities //! - [anstyle-lossy](https://docs.rs/anstyle-lossy): Convert between `anstyle::Color` types diff --git a/crates/anstyle/src/reset.rs b/crates/anstyle/src/reset.rs index f35b8d95..62c8b4bc 100644 --- a/crates/anstyle/src/reset.rs +++ b/crates/anstyle/src/reset.rs @@ -1,4 +1,5 @@ /// Reset terminal formatting +#[allow(clippy::exhaustive_structs)] #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Reset; @@ -7,7 +8,7 @@ impl Reset { /// /// `Reset` also implements `Display` directly, so calling this method is optional. #[inline] - pub fn render(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render(self) -> impl core::fmt::Display + Copy { self } } diff --git a/crates/anstyle/src/style.rs b/crates/anstyle/src/style.rs index 2e93b41b..e12a5df0 100644 --- a/crates/anstyle/src/style.rs +++ b/crates/anstyle/src/style.rs @@ -101,7 +101,7 @@ impl Style { /// /// `Style` also implements `Display` directly, so calling this method is optional. #[inline] - pub fn render(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render(self) -> impl core::fmt::Display + Copy { StyleDisplay(self) } @@ -150,7 +150,7 @@ impl Style { /// /// Unlike [`Reset::render`][crate::Reset::render], this will elide the code if there is nothing to reset. #[inline] - pub fn render_reset(self) -> impl core::fmt::Display + Copy + Clone { + pub fn render_reset(self) -> impl core::fmt::Display + Copy { if self != Self::new() { RESET } else { @@ -289,27 +289,32 @@ impl Style { /// # Reflection impl Style { + /// Get the foreground color #[inline] pub const fn get_fg_color(self) -> Option { self.fg } + /// Get the background color #[inline] + #[allow(missing_docs)] pub const fn get_bg_color(self) -> Option { self.bg } #[inline] + #[allow(missing_docs)] pub const fn get_underline_color(self) -> Option { self.underline } #[inline] + #[allow(missing_docs)] pub const fn get_effects(self) -> crate::Effects { self.effects } - /// Check if no effects are enabled + /// Check if no styling is enabled #[inline] pub const fn is_plain(self) -> bool { self.fg.is_none() @@ -395,7 +400,7 @@ impl core::ops::SubAssign for Style { /// assert_ne!(anstyle::Effects::UNDERLINE | effects, effects); /// assert_ne!(anstyle::RgbColor(0, 0, 0).on_default() | effects, effects); /// ``` -impl core::cmp::PartialEq for Style { +impl PartialEq for Style { #[inline] fn eq(&self, other: &crate::Effects) -> bool { let other = Self::from(*other); diff --git a/crates/colorchoice-clap/src/lib.rs b/crates/colorchoice-clap/src/lib.rs index a766f89b..49532b24 100644 --- a/crates/colorchoice-clap/src/lib.rs +++ b/crates/colorchoice-clap/src/lib.rs @@ -30,6 +30,7 @@ pub use clap::ColorChoice; /// Mixin a clap argument for colored output selection +#[allow(clippy::exhaustive_structs)] #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, clap::Args)] #[command(about = None, long_about = None)] pub struct Color { @@ -67,6 +68,6 @@ mod test { } use clap::CommandFactory; - Cli::command().debug_assert() + Cli::command().debug_assert(); } } diff --git a/crates/colorchoice/src/lib.rs b/crates/colorchoice/src/lib.rs index 8888d616..82bdd337 100644 --- a/crates/colorchoice/src/lib.rs +++ b/crates/colorchoice/src/lib.rs @@ -8,11 +8,19 @@ use core::sync::atomic::{AtomicUsize, Ordering}; /// Selection for overriding color output +#[allow(clippy::exhaustive_enums)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ColorChoice { + /// Use colors if the output device appears to support them Auto, + /// Like `Always`, except it never tries to use anything other than emitting ANSI + /// color codes. AlwaysAnsi, + /// Try very hard to emit colors. + /// + /// This includes emitting ANSI colors on Windows if the console API is unavailable. Always, + /// Never emit colors. Never, } @@ -24,7 +32,7 @@ impl ColorChoice { /// Override the detected [`ColorChoice`] pub fn write_global(self) { - USER.set(self) + USER.set(self); } } @@ -46,17 +54,17 @@ impl AtomicChoice { ))) } - pub(crate) fn get(&self) -> crate::ColorChoice { + pub(crate) fn get(&self) -> ColorChoice { let choice = self.0.load(Ordering::SeqCst); - Self::to_choice(choice).unwrap() + Self::to_choice(choice).expect("Only `ColorChoice` values can be `set`") } - pub(crate) fn set(&self, choice: crate::ColorChoice) { + pub(crate) fn set(&self, choice: ColorChoice) { let choice = Self::from_choice(choice); self.0.store(choice, Ordering::SeqCst); } - const fn from_choice(choice: crate::ColorChoice) -> usize { + const fn from_choice(choice: ColorChoice) -> usize { match choice { crate::ColorChoice::Auto => 0, crate::ColorChoice::AlwaysAnsi => 1, @@ -65,7 +73,7 @@ impl AtomicChoice { } } - const fn to_choice(choice: usize) -> Option { + const fn to_choice(choice: usize) -> Option { match choice { 0 => Some(crate::ColorChoice::Auto), 1 => Some(crate::ColorChoice::AlwaysAnsi),