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