1#[allow(unused_imports)]
2use crate::{
3 AnsiColors, BgDynColorDisplay, CssColors, DynColor, FgDynColorDisplay, Rgb, XtermColors,
4};
5use core::fmt;
6
7#[allow(missing_docs)]
12#[derive(Copy, Clone, PartialEq, Eq, Debug)]
13pub enum DynColors {
14 Ansi(AnsiColors),
15 Css(CssColors),
16 Xterm(XtermColors),
17 Rgb(u8, u8, u8),
18}
19
20impl crate::private::Sealed for DynColors {}
21
22impl DynColor for DynColors {
23 fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 DynColors::Ansi(ansi) => ansi.fmt_ansi_fg(f),
26 DynColors::Css(css) => css.fmt_ansi_fg(f),
27 DynColors::Xterm(xterm) => xterm.fmt_ansi_fg(f),
28 &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_ansi_fg(f),
29 }
30 }
31
32 fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 match self {
34 DynColors::Ansi(ansi) => ansi.fmt_ansi_bg(f),
35 DynColors::Css(css) => css.fmt_ansi_bg(f),
36 DynColors::Xterm(xterm) => xterm.fmt_ansi_bg(f),
37 &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_ansi_bg(f),
38 }
39 }
40
41 fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 match self {
43 DynColors::Ansi(ansi) => ansi.fmt_raw_ansi_fg(f),
44 DynColors::Css(css) => css.fmt_raw_ansi_fg(f),
45 DynColors::Xterm(xterm) => xterm.fmt_raw_ansi_fg(f),
46 &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_raw_ansi_fg(f),
47 }
48 }
49
50 fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 match self {
52 DynColors::Ansi(ansi) => ansi.fmt_raw_ansi_bg(f),
53 DynColors::Css(css) => css.fmt_raw_ansi_bg(f),
54 DynColors::Xterm(xterm) => xterm.fmt_raw_ansi_bg(f),
55 &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_raw_ansi_bg(f),
56 }
57 }
58
59 #[doc(hidden)]
60 fn get_dyncolors_fg(&self) -> crate::DynColors {
61 *self
62 }
63
64 #[doc(hidden)]
65 fn get_dyncolors_bg(&self) -> crate::DynColors {
66 *self
67 }
68}
69
70#[derive(Debug)]
72pub struct ParseColorError;
73
74impl core::str::FromStr for DynColors {
75 type Err = ParseColorError;
76
77 fn from_str(s: &str) -> Result<Self, Self::Err> {
78 if s.chars().next().ok_or(ParseColorError)? == '#' {
79 match s.len() {
80 4 => {
81 Err(ParseColorError)
83 }
84 7 => Ok(Self::Rgb(
85 u8::from_str_radix(&s[1..3], 16).or(Err(ParseColorError))?,
86 u8::from_str_radix(&s[3..5], 16).or(Err(ParseColorError))?,
87 u8::from_str_radix(&s[5..7], 16).or(Err(ParseColorError))?,
88 )),
89 _ => Err(ParseColorError),
90 }
91 } else {
92 let ansi = match s {
93 "black" => AnsiColors::Black,
94 "red" => AnsiColors::Red,
95 "green" => AnsiColors::Green,
96 "yellow" => AnsiColors::Yellow,
97 "blue" => AnsiColors::Blue,
98 "magenta" | "purple" => AnsiColors::Magenta,
99 "cyan" => AnsiColors::Cyan,
100 "white" => AnsiColors::White,
101 "bright black" => AnsiColors::BrightBlack,
102 "bright red" => AnsiColors::BrightRed,
103 "bright green" => AnsiColors::BrightGreen,
104 "bright yellow" => AnsiColors::BrightYellow,
105 "bright blue" => AnsiColors::BrightBlue,
106 "bright magenta" => AnsiColors::BrightMagenta,
107 "bright cyan" => AnsiColors::BrightCyan,
108 "bright white" => AnsiColors::BrightWhite,
109 _ => return Err(ParseColorError),
110 };
111
112 Ok(Self::Ansi(ansi))
113 }
114 }
115}