Nothing to see here, move along meow
1use core::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub struct Rgb {
5 pub r: u8,
6 pub g: u8,
7 pub b: u8,
8}
9
10impl Rgb {
11 pub const fn new(r: u8, g: u8, b: u8) -> Self {
12 Self { r, g, b }
13 }
14
15 pub const fn from_hex(hex: u32) -> Self {
16 Self {
17 r: ((hex >> 16) & 0xFF) as u8,
18 g: ((hex >> 8) & 0xFF) as u8,
19 b: (hex & 0xFF) as u8,
20 }
21 }
22
23 pub const fn to_pixel(self) -> u32 {
24 ((self.r as u32) << 16) | ((self.g as u32) << 8) | (self.b as u32)
25 }
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29#[repr(u8)]
30pub enum BasicColor {
31 Black = 0,
32 Red = 1,
33 Green = 2,
34 Yellow = 3,
35 Blue = 4,
36 Magenta = 5,
37 Cyan = 6,
38 White = 7,
39 BrightBlack = 8,
40 BrightRed = 9,
41 BrightGreen = 10,
42 BrightYellow = 11,
43 BrightBlue = 12,
44 BrightMagenta = 13,
45 BrightCyan = 14,
46 BrightWhite = 15,
47}
48
49impl BasicColor {
50 const fn sgr_fg(self) -> u8 {
51 match self as u8 {
52 c @ 0..=7 => 30 + c,
53 c => 82 + c,
54 }
55 }
56
57 const fn sgr_bg(self) -> u8 {
58 match self as u8 {
59 c @ 0..=7 => 40 + c,
60 c => 92 + c,
61 }
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum Color {
67 Truecolor(Rgb),
68 Basic(BasicColor),
69}
70
71impl Color {
72 pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
73 Self::Truecolor(Rgb::new(r, g, b))
74 }
75
76 pub const fn hex(val: u32) -> Self {
77 Self::Truecolor(Rgb::from_hex(val))
78 }
79
80 pub const fn basic(c: BasicColor) -> Self {
81 Self::Basic(c)
82 }
83}
84
85pub struct Fg(pub Color);
86pub struct Bg(pub Color);
87pub struct Bold;
88pub struct Dim;
89pub struct Reset;
90
91impl fmt::Display for Fg {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 match self.0 {
94 Color::Truecolor(rgb) => write!(f, "\x1b[38;2;{};{};{}m", rgb.r, rgb.g, rgb.b),
95 Color::Basic(c) => write!(f, "\x1b[{}m", c.sgr_fg()),
96 }
97 }
98}
99
100impl fmt::Display for Bg {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 match self.0 {
103 Color::Truecolor(rgb) => write!(f, "\x1b[48;2;{};{};{}m", rgb.r, rgb.g, rgb.b),
104 Color::Basic(c) => write!(f, "\x1b[{}m", c.sgr_bg()),
105 }
106 }
107}
108
109impl fmt::Display for Bold {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 f.write_str("\x1b[1m")
112 }
113}
114
115impl fmt::Display for Dim {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.write_str("\x1b[2m")
118 }
119}
120
121impl fmt::Display for Reset {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 f.write_str("\x1b[0m")
124 }
125}
126
127pub struct FgBasic(pub BasicColor);
128pub struct BgBasic(pub BasicColor);
129
130impl fmt::Display for FgBasic {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 write!(f, "\x1b[{}m", self.0.sgr_fg())
133 }
134}
135
136impl fmt::Display for BgBasic {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 write!(f, "\x1b[{}m", self.0.sgr_bg())
139 }
140}
141
142pub struct FgRgb(pub Rgb);
143pub struct BgRgb(pub Rgb);
144
145impl fmt::Display for FgRgb {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 write!(f, "\x1b[38;2;{};{};{}m", self.0.r, self.0.g, self.0.b)
148 }
149}
150
151impl fmt::Display for BgRgb {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 write!(f, "\x1b[48;2;{};{};{}m", self.0.r, self.0.g, self.0.b)
154 }
155}