create_farm/utils/
colors.rs

1#![allow(unused)]
2use std::fmt;
3
4pub const BLACK: &str = "\x1b[30m";
5pub const RED: &str = "\x1b[31m";
6pub const GREEN: &str = "\x1b[32m";
7pub const YELLOW: &str = "\x1b[33m";
8pub const BLUE: &str = "\x1b[34m";
9pub const WHITE: &str = "\x1b[37m";
10pub const RESET: &str = "\x1b[0m";
11pub const BOLD: &str = "\x1b[1m";
12pub const ITALIC: &str = "\x1b[3m";
13pub const DIM: &str = "\x1b[2m";
14pub const DIMRESET: &str = "\x1b[22m";
15
16pub fn remove_colors(s: &str) -> String {
17  s.replace(BLACK, "")
18    .replace(RED, "")
19    .replace(GREEN, "")
20    .replace(YELLOW, "")
21    .replace(BLUE, "")
22    .replace(WHITE, "")
23    .replace(RESET, "")
24    .replace(BOLD, "")
25    .replace(ITALIC, "")
26    .replace(DIM, "")
27    .replace(DIMRESET, "")
28}
29
30type StylerEnabled = fn(&str) -> String;
31type ColorFunction = fn(&str) -> String;
32
33// brand gradient colors
34const GRADIENT_PURPLE_COLOR: [u8; 3] = [176, 106, 179];
35const GRADIENT_PINK_COLOR: [u8; 3] = [198, 66, 110];
36const BRAND_GRADIENT_COLORS: [u8; 3] = [255, 182, 193];
37const BRAND_GRADIENT_COLORS2: [u8; 3] = [128, 0, 128];
38
39pub fn is_color_enabled() -> bool {
40  true
41}
42
43pub fn create_formatter<'a>(
44  open: &'a str,
45  close: &'a str,
46  replace: Option<&'a str>,
47) -> impl Fn(&'a str) -> String + 'a {
48  move |input| {
49    let string = input.to_string();
50    let index = string.find(close).unwrap_or(open.len());
51    if let Some(replace_str) = replace {
52      let mut result = String::new();
53      result.push_str(open);
54      result.push_str(&replace_close(&string, close, replace_str, index));
55      result.push_str(close);
56      result
57    } else {
58      format!("{open}{string}{close}")
59    }
60  }
61}
62
63pub fn replace_close(string: &str, close: &str, replace: &str, index: usize) -> String {
64  let (start, end) = string.split_at(index);
65  let next_index_option = end.find(close).map(|i| i + close.len());
66  let next_index = next_index_option.unwrap_or(0);
67  if next_index != 0 {
68    format!(
69      "{}{}{}",
70      start,
71      replace,
72      replace_close(&end[next_index..], close, replace, next_index)
73    )
74  } else {
75    format!("{start}{replace}")
76  }
77}
78
79pub fn reset(s: &str) -> String {
80  if is_color_enabled() {
81    format!("\x1b[0m{s}")
82  } else {
83    s.to_string()
84  }
85}
86
87pub fn bold(s: &str) -> String {
88  if is_color_enabled() {
89    create_formatter("\x1b[1m", "\x1b[22m", Some("\x1b[22m\x1b[1m"))(s)
90  } else {
91    s.to_string()
92  }
93}
94
95pub fn dim(s: &str) -> String {
96  if is_color_enabled() {
97    create_formatter("\x1b[2m", "\x1b[22m", Some("\x1b[22m\x1b[2m"))(s)
98  } else {
99    s.to_string()
100  }
101}
102
103pub fn italic(s: &str) -> String {
104  if is_color_enabled() {
105    create_formatter("\x1b[3m", "\x1b[23m", None)(s)
106  } else {
107    s.to_string()
108  }
109}
110
111pub fn underline(s: &str) -> String {
112  if is_color_enabled() {
113    create_formatter("\x1b[4m", "\x1b[24m", None)(s)
114  } else {
115    s.to_string()
116  }
117}
118
119pub fn inverse(s: &str) -> String {
120  if is_color_enabled() {
121    create_formatter("\x1b[7m", "\x1b[27m", None)(s)
122  } else {
123    s.to_string()
124  }
125}
126
127pub fn hidden(s: &str) -> String {
128  if is_color_enabled() {
129    create_formatter("\x1b[8m", "\x1b[28m", None)(s)
130  } else {
131    s.to_string()
132  }
133}
134
135pub fn strikethrough(s: &str) -> String {
136  if is_color_enabled() {
137    create_formatter("\x1b[9m", "\x1b[29m", None)(s)
138  } else {
139    s.to_string()
140  }
141}
142
143pub fn debug_color(s: &str) -> String {
144  if is_color_enabled() {
145    create_formatter("\x1b[38;2;255;140;0m", "\x1b[39m", None)(s)
146  } else {
147    s.to_string()
148  }
149}
150
151pub fn brand_color(s: &str) -> String {
152  if is_color_enabled() {
153    create_formatter("\x1b[38;2;113;26;95m", "\x1b[39m", None)(s)
154  } else {
155    s.to_string()
156  }
157}
158
159// black
160pub fn black(s: &str) -> String {
161  if is_color_enabled() {
162    create_formatter("\x1b[38;2;0;0;0m", "\x1b[39m", None)(s)
163  } else {
164    s.to_string()
165  }
166}
167
168pub fn red(s: &str) -> String {
169  if is_color_enabled() {
170    create_formatter("\x1b[38;2;219;90;107m", "\x1b[39m", None)(s)
171  } else {
172    s.to_string()
173  }
174}
175
176pub fn green(s: &str) -> String {
177  if is_color_enabled() {
178    create_formatter("\x1b[32m", "\x1b[39m", None)(s)
179  } else {
180    s.to_string()
181  }
182}
183
184pub fn yellow(s: &str) -> String {
185  if is_color_enabled() {
186    create_formatter("\x1b[33m", "\x1b[39m", None)(s)
187  } else {
188    s.to_string()
189  }
190}
191
192pub fn blue(s: &str) -> String {
193  if is_color_enabled() {
194    create_formatter("\x1b[38;2;68;206;246m", "\x1b[39m", None)(s)
195  } else {
196    s.to_string()
197  }
198}
199
200pub fn magenta(s: &str) -> String {
201  if is_color_enabled() {
202    create_formatter("\x1b[38;2;180;0;100m", "\x1b[39m", None)(s)
203  } else {
204    s.to_string()
205  }
206}
207
208pub fn purple(s: &str) -> String {
209  if is_color_enabled() {
210    create_formatter("\x1b[38;2;140;67;86m", "\x1b[39m", None)(s)
211  } else {
212    s.to_string()
213  }
214}
215
216pub fn orange(s: &str) -> String {
217  if is_color_enabled() {
218    create_formatter("\x1b[38;2;255;137;54m", "\x1b[39m", None)(s)
219  } else {
220    s.to_string()
221  }
222}
223
224pub fn cyan(s: &str) -> String {
225  if is_color_enabled() {
226    create_formatter("\x1b[36m", "\x1b[39m", None)(s)
227  } else {
228    s.to_string()
229  }
230}
231
232pub fn white(s: &str) -> String {
233  if is_color_enabled() {
234    create_formatter("\x1b[37m", "\x1b[39m", None)(s)
235  } else {
236    s.to_string()
237  }
238}
239
240pub fn bg_black(s: &str) -> String {
241  if is_color_enabled() {
242    create_formatter("\x1b[40m", "\x1b[49m", None)(s)
243  } else {
244    s.to_string()
245  }
246}
247
248pub fn bg_red(s: &str) -> String {
249  if is_color_enabled() {
250    create_formatter("\x1b[41m", "\x1b[49m", None)(s)
251  } else {
252    s.to_string()
253  }
254}
255
256pub fn bg_green(s: &str) -> String {
257  if is_color_enabled() {
258    create_formatter("\x1b[42m", "\x1b[49m", None)(s)
259  } else {
260    s.to_string()
261  }
262}
263
264pub fn bg_yellow(s: &str) -> String {
265  if is_color_enabled() {
266    create_formatter("\x1b[43m", "\x1b[49m", None)(s)
267  } else {
268    s.to_string()
269  }
270}
271
272pub fn bg_blue(s: &str) -> String {
273  if is_color_enabled() {
274    create_formatter("\x1b[44m", "\x1b[49m", None)(s)
275  } else {
276    s.to_string()
277  }
278}
279
280pub fn bg_magenta(s: &str) -> String {
281  if is_color_enabled() {
282    create_formatter("\x1b[45m", "\x1b[49m", None)(s)
283  } else {
284    s.to_string()
285  }
286}
287
288pub fn bg_cyan(s: &str) -> String {
289  if is_color_enabled() {
290    create_formatter("\x1b[46m", "\x1b[49m", None)(s)
291  } else {
292    s.to_string()
293  }
294}
295
296pub fn bg_white(s: &str) -> String {
297  if is_color_enabled() {
298    create_formatter("\x1b[47m", "\x1b[49m", None)(s)
299  } else {
300    s.to_string()
301  }
302}
303
304pub fn gradient_string(text: &str, colors: &[[u8; 3]]) -> String {
305  let steps = text.len();
306  let gradient = colors
307    .iter()
308    .map(|color| format!("\x1b[38;2;{};{};{}m", color[0], color[1], color[2]))
309    .collect::<Vec<_>>();
310
311  let mut output = String::new();
312
313  for (i, c) in text.chars().enumerate() {
314    let color_index = ((i as f64) / (steps as f64) * (colors.len() as f64 - 1.0)).floor() as usize;
315    output += &format!("{}{}", gradient[color_index], c);
316  }
317
318  output += "\x1b[0m";
319  output
320}
321
322pub fn interpolate_color(color1: &[u8; 3], color2: &[u8; 3], factor: f64) -> [u8; 3] {
323  [
324    (color1[0] as f64 + (color2[0] as f64 - color1[0] as f64) * factor).round() as u8,
325    (color1[1] as f64 + (color2[1] as f64 - color1[1] as f64) * factor).round() as u8,
326    (color1[2] as f64 + (color2[2] as f64 - color1[2] as f64) * factor).round() as u8,
327  ]
328}
329
330pub fn persistent_cache_brand() -> String {
331  let gradient_string = gradient_string(
332    "FULL EXTREME!",
333    &[
334      GRADIENT_PURPLE_COLOR,
335      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.1),
336      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.2),
337      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.3),
338      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.4),
339      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.5),
340      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.6),
341      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.7),
342      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.8),
343      interpolate_color(&GRADIENT_PURPLE_COLOR, &GRADIENT_PINK_COLOR, 0.9),
344      GRADIENT_PINK_COLOR,
345    ],
346  );
347  format!("{}{}{}", brand_color("⚡️"), gradient_string, reset(""))
348}
349
350pub fn handle_brand_text(text: &str) {
351  let gradient_string = gradient_string(
352    text,
353    &[
354      BRAND_GRADIENT_COLORS,
355      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.2),
356      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.4),
357      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.6),
358      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.8),
359      BRAND_GRADIENT_COLORS2,
360    ],
361  );
362  println!("{gradient_string}");
363}
364
365pub fn brand_text(text: &str) -> String {
366  let gradient_string = gradient_string(
367    &format!("\n{text} \n"),
368    &[
369      BRAND_GRADIENT_COLORS,
370      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.2),
371      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.4),
372      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.6),
373      interpolate_color(&BRAND_GRADIENT_COLORS, &BRAND_GRADIENT_COLORS2, 0.8),
374      BRAND_GRADIENT_COLORS2,
375    ],
376  );
377  gradient_string
378}
379
380pub struct Colors {
381  pub reset: StylerEnabled,
382  pub bold: StylerEnabled,
383  pub dim: StylerEnabled,
384  pub italic: StylerEnabled,
385  pub underline: StylerEnabled,
386  pub inverse: StylerEnabled,
387  pub hidden: StylerEnabled,
388  pub strikethrough: StylerEnabled,
389  pub black: StylerEnabled,
390  pub red: StylerEnabled,
391  pub green: StylerEnabled,
392  pub yellow: StylerEnabled,
393  pub blue: StylerEnabled,
394  pub magenta: StylerEnabled,
395  pub purple: StylerEnabled,
396  pub orange: StylerEnabled,
397  pub cyan: StylerEnabled,
398  pub white: StylerEnabled,
399  pub bg_black: StylerEnabled,
400  pub bg_red: StylerEnabled,
401  pub bg_green: StylerEnabled,
402  pub bg_yellow: StylerEnabled,
403  pub bg_blue: StylerEnabled,
404  pub bg_magenta: StylerEnabled,
405  pub bg_cyan: StylerEnabled,
406  pub bg_white: StylerEnabled,
407  pub debug_color: StylerEnabled,
408  pub brand_color: StylerEnabled,
409  pub handle_brand_text: fn(&str),
410  pub brand_text: fn(&str) -> String,
411}