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