1use std::{
5 collections::HashMap,
6 fmt::{Display, Formatter},
7};
8use serde::{Serialize, Deserialize};
9use lazy_static::lazy_static;
10
11#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default,
44 Serialize, Deserialize)]
45#[repr(i32)]
46pub enum Color
47{
48 None = 0,
49 Black = 1,
50 #[default]
51 Blue = 2,
52 Cyan = 3,
53 Green = 4,
54 Gray = 5,
55 Magenta = 6,
56 Red = 7,
57 White = 8,
58 Yellow = 9,
59
60 Custom(String) = 10,
61}
62
63static BLACK: &str = "\x1b[30m";
64static BLUE: &str = "\x1b[34m";
65static CYAN: &str = "\x1b[36m";
66static GREEN: &str = "\x1b[32m";
67static GRAY: &str = "\x1b[90m";
68static MAGENTA: &str = "\x1b[35m";
69static RED: &str = "\x1b[31m";
70static WHITE: &str = "\x1b[37m";
71static YELLOW: &str = "\x1b[33m";
72
73pub(crate) static RESET: &str = "\x1b[0m";
74
75lazy_static! {
76 static ref COLOR_MAP: HashMap<i32, &'static str> = {
77 let mut m = HashMap::new();
78 m.insert(Color::None.into(), "");
79 m.insert(Color::Black.into(), BLACK);
80 m.insert(Color::Blue.into(), BLUE);
81 m.insert(Color::Cyan.into(), CYAN);
82 m.insert(Color::Green.into(), GREEN);
83 m.insert(Color::Gray.into(), GRAY);
84 m.insert(Color::Magenta.into(), MAGENTA);
85 m.insert(Color::Red.into(), RED);
86 m.insert(Color::White.into(), WHITE);
87 m.insert(Color::Yellow.into(), YELLOW);
88 return m;
89 };
90}
91
92pub fn color_text(text: &str, color: Color) -> String {
111 match color {
112 Color::Custom(s) => {
113 return s + text + RESET;
114 },
115 _ => {
116 if color != Color::None {
117 return COLOR_MAP[&(color.into())].to_string() + text + RESET;
118 }
119 else{
120 return String::from(text)
121 }
122 }
123 }
124}
125
126impl Display for Color {
127 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
128 let level_str = match self {
129 Color::None => "None",
130 Color:: Black => "Black",
131 Color::Blue => "Blue",
132 Color::Cyan => "Cyan",
133 Color::Green => "Green",
134 Color::Gray => "Gray",
135 Color::Magenta => "Magenta",
136 Color::Red => "Red",
137 Color::White => "White",
138 Color::Yellow => "Yellow",
139
140 Color::Custom(str) => &format!("'{}'", str)
141 };
142 return write!(f, "{}", level_str)
143 }
144}
145
146impl TryFrom<i32> for Color {
147 type Error = &'static str;
148 fn try_from(value: i32) -> Result<Self, Self::Error> {
149 match value {
150 0 => Ok(Color::None),
151 1 => Ok(Color::Black),
152 2 => Ok(Color::Blue),
153 3 => Ok(Color::Cyan),
154 4 => Ok(Color::Green),
155 5 => Ok(Color::Gray),
156 6 => Ok(Color::Magenta),
157 7 => Ok(Color::Red),
158 8 => Ok(Color::White),
159 9 => Ok(Color::Yellow),
160 18 => {Ok(Color::Custom(String::new()))}
161 _ => Err("Invalid value! Please provide a value in range 0-9."),
162 }
163 }
164}
165
166impl From<Color> for i32 {
167 fn from(color: Color) -> Self {
168 match color {
169 Color::None => 0,
170 Color::Black => 1,
171 Color::Blue => 2,
172 Color::Cyan => 3,
173 Color::Green => 4,
174 Color::Gray => 5,
175 Color::Magenta => 6,
176 Color::Red => 7,
177 Color::White => 8,
178 Color::Yellow => 9,
179 Color::Custom(_) => 10,
180 }
181 }
182}
183
184impl AsRef<str> for Color {
185 fn as_ref(&self) -> &str {
186 match self {
187 Color::None => "None",
188 Color:: Black => "Black",
189 Color::Blue => "Blue",
190 Color::Cyan => "Cyan",
191 Color::Green => "Green",
192 Color::Gray => "Gray",
193 Color::Magenta => "Magenta",
194 Color::Red => "Red",
195 Color::White => "White",
196 Color::Yellow => "Yellow",
197 Color::Custom(str) => str.as_str(),
198 }
199 }
200}