1use std::fmt::Display;
2
3pub fn fg<T: Display>(text: T, fg: usize) -> String {
4 format!("\x1b[1;38;5;{}m{}", wrap(fg), text)
5}
6pub fn bg<T: Display>(text: T, bg: usize) -> String {
7 format!("\x1b[1;48;5;{}m{}", wrap(bg), text)
8}
9pub fn reset<T: Display>(text: T) -> String {
10 format!("{}\x1b[0m", text)
11}
12pub fn bgfg<T: Display>(text: T, fore: usize, back: usize) -> String {
13 bg(fg(text, wrap(fore) as usize), wrap(back) as usize)
14}
15pub fn ansi<T: Display>(text: T, fore: usize, back: usize) -> String {
16 reset(bgfg(text, fore as usize, back as usize))
17}
18pub fn ansi_clear() -> String {
19 "\x1b[2J\x1b[3J\x1b[H".to_string()
20}
21pub fn fore<T: Display>(text: T, fore: usize) -> String {
22 let (fore, back) = couple(fore);
23 ansi(text, fore as usize, back as usize)
24}
25pub fn back<T: Display>(text: T, back: usize) -> String {
26 let (back, fore) = couple(back);
27 ansi(text, fore as usize, back as usize)
28}
29pub fn auto<T: Display>(word: T) -> String {
30 let color = from_string(word.to_string());
31 fg(word.to_string(), color.into())
32}
33pub fn from_string<T: Display>(word: T) -> u8 {
34 from_bytes(word.to_string().as_bytes())
35}
36pub fn rgb_from_string<T: Display>(word: T) -> [u8; 3] {
37 rgb_from_bytes(word.to_string().as_bytes())
38}
39pub fn from_bytes(bytes: &[u8]) -> u8 {
40 let mut color: u8 = 0;
41 for rgb in rgb_from_bytes(bytes) {
42 color = color ^ rgb
43 }
44 color
45}
46pub fn rgb_from_bytes(bytes: &[u8]) -> [u8; 3] {
47 let mut color: [u8; 3] = [0, 0, 0];
48 for (index, byte) in bytes.iter().enumerate() {
49 color[index % 3] = *byte
50 }
51 color
52}
53
54pub fn couple(color: usize) -> (u8, u8) {
55 let fore = wrap(color);
56 let back = invert_bw(fore);
57 (fore, back)
58}
59
60pub fn invert_bw(color: u8) -> u8 {
61 match color {
62 0 | 8 | 16..21 | 52..61 | 88..93 | 232..239 => 231,
63 _ => 16,
64 }
65}
66
67pub fn wrap(color: usize) -> u8 {
68 (if color > 0 { color % 255 } else { color }) as u8
69}