1use anstyle::RgbColor as Rgb;
5
6#[allow(clippy::exhaustive_structs)]
8#[derive(Copy, Clone, PartialEq, Eq, Debug)]
9pub struct Palette(pub RawPalette);
10type RawPalette = [Rgb; 16];
11
12impl Palette {
13 pub const fn get(&self, color: anstyle::AnsiColor) -> Rgb {
15 let color = anstyle::Ansi256Color::from_ansi(color);
16 *self.get_ansi256_ref(color)
17 }
18 const fn get_ansi256_ref(&self, color: anstyle::Ansi256Color) -> &Rgb {
19 let index = color.index() as usize;
20 &self.0[index]
21 }
22
23 pub(crate) const fn rgb_from_ansi(&self, color: anstyle::AnsiColor) -> anstyle::RgbColor {
24 self.get(color)
25 }
26
27 pub(crate) const fn rgb_from_index(&self, index: u8) -> Option<anstyle::RgbColor> {
28 let index = index as usize;
29 if index < self.0.len() {
30 Some(self.0[index])
31 } else {
32 None
33 }
34 }
35
36 pub(crate) const fn find_match(&self, color: anstyle::RgbColor) -> anstyle::AnsiColor {
37 let mut best_index = 0;
38 let mut best_distance = crate::distance(color, self.0[best_index]);
39
40 let mut index = best_index + 1;
41 while index < self.0.len() {
42 let distance = crate::distance(color, self.0[index]);
43 if distance < best_distance {
44 best_index = index;
45 best_distance = distance;
46 }
47
48 index += 1;
49 }
50
51 if let Some(color) = anstyle::Ansi256Color(best_index as u8).into_ansi() {
52 color
53 } else {
54 #[allow(clippy::no_effect)]
56 ["best_index is out of bounds"][best_index];
57 anstyle::AnsiColor::Black
59 }
60 }
61}
62
63impl Default for Palette {
64 fn default() -> Self {
65 DEFAULT
66 }
67}
68
69impl std::ops::Index<anstyle::AnsiColor> for Palette {
70 type Output = Rgb;
71
72 #[inline]
73 fn index(&self, color: anstyle::AnsiColor) -> &Rgb {
74 let color = anstyle::Ansi256Color::from_ansi(color);
75 self.get_ansi256_ref(color)
76 }
77}
78
79impl From<RawPalette> for Palette {
80 fn from(raw: RawPalette) -> Self {
81 Self(raw)
82 }
83}
84
85#[cfg(not(windows))]
87pub use VGA as DEFAULT;
88
89#[cfg(windows)]
91pub use WIN10_CONSOLE as DEFAULT;
92
93pub const VGA: Palette = Palette([
95 Rgb(0, 0, 0),
96 Rgb(170, 0, 0),
97 Rgb(0, 170, 0),
98 Rgb(170, 85, 0),
99 Rgb(0, 0, 170),
100 Rgb(170, 0, 170),
101 Rgb(0, 170, 170),
102 Rgb(170, 170, 170),
103 Rgb(85, 85, 85),
104 Rgb(255, 85, 85),
105 Rgb(85, 255, 85),
106 Rgb(255, 255, 85),
107 Rgb(85, 85, 255),
108 Rgb(255, 85, 255),
109 Rgb(85, 255, 255),
110 Rgb(255, 255, 255),
111]);
112
113pub const WIN10_CONSOLE: Palette = Palette([
115 Rgb(12, 12, 12),
116 Rgb(197, 15, 31),
117 Rgb(19, 161, 14),
118 Rgb(193, 156, 0),
119 Rgb(0, 55, 218),
120 Rgb(136, 23, 152),
121 Rgb(58, 150, 221),
122 Rgb(204, 204, 204),
123 Rgb(118, 118, 118),
124 Rgb(231, 72, 86),
125 Rgb(22, 198, 12),
126 Rgb(249, 241, 165),
127 Rgb(59, 120, 255),
128 Rgb(180, 0, 158),
129 Rgb(97, 214, 214),
130 Rgb(242, 242, 242),
131]);