mvutils/
print.rs

1use std::fmt::Display;
2use std::io::Write;
3
4#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
5pub enum Fmt {
6    Default,
7    Bold,
8    Underline,
9    UnderlineStop,
10}
11
12#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
13pub enum Col {
14    Black,
15    Red,
16    Green,
17    Yellow,
18    Blue,
19    Purple,
20    DarkCyan,
21    Grey,
22    DarkGrey,
23    BrightRed,
24    Lime,
25    BrightYellow,
26    BrightBlue,
27    Magenta,
28    Cyan,
29    White,
30}
31
32macro_rules! f {
33    ($s:expr) => {
34        format!("{}[{}m", 27 as char, $s).as_str()
35    };
36}
37
38pub struct Printer {
39    s: String,
40    last_col: Col,
41    last_bg: Col,
42    last_fmt: Fmt,
43}
44
45impl Printer {
46    pub fn start() -> Self {
47        Printer {
48            s: "".to_string(),
49            last_col: Col::White,
50            last_bg: Col::Black,
51            last_fmt: Fmt::Default,
52        }
53    }
54
55    pub fn text(mut self, text: &str) -> Self {
56        self.s.push_str(text);
57        self
58    }
59
60    pub fn text_ln(self, text: &str) -> Self {
61        let f = self.last_fmt;
62        let c = self.last_col;
63        let g = self.last_bg;
64        self.text(text).def().ln().col(c).bg(g).fmt(f)
65    }
66
67    pub fn ln(mut self) -> Self {
68        let f = self.last_fmt;
69        let c = self.last_col;
70        let b = self.last_bg;
71        self.s.push_str(f!(0));
72        self.s.push(10 as char);
73        self.col(c).bg(b).fmt(f)
74    }
75
76    pub fn fmt(mut self, fmt: Fmt) -> Self {
77        match fmt {
78            Fmt::Default => self.s.push_str(f!(0)),
79            Fmt::Bold => self.s.push_str(f!(1)),
80            Fmt::Underline => self.s.push_str(f!(4)),
81            Fmt::UnderlineStop => self.s.push_str(f!(24)),
82        }
83        self.last_fmt = fmt;
84        self
85    }
86
87    pub fn def(self) -> Self {
88        self.fmt(Fmt::Default)
89    }
90
91    pub fn col(mut self, col: Col) -> Self {
92        match col {
93            Col::Black => self.s.push_str(f!(30)),
94            Col::Red => self.s.push_str(f!(31)),
95            Col::Green => self.s.push_str(f!(32)),
96            Col::Yellow => self.s.push_str(f!(33)),
97            Col::Blue => self.s.push_str(f!(34)),
98            Col::Purple => self.s.push_str(f!(35)),
99            Col::DarkCyan => self.s.push_str(f!(36)),
100            Col::Grey => self.s.push_str(f!(37)),
101            Col::DarkGrey => self.s.push_str(f!(90)),
102            Col::BrightRed => self.s.push_str(f!(91)),
103            Col::Lime => self.s.push_str(f!(92)),
104            Col::BrightYellow => self.s.push_str(f!(93)),
105            Col::BrightBlue => self.s.push_str(f!(94)),
106            Col::Magenta => self.s.push_str(f!(95)),
107            Col::Cyan => self.s.push_str(f!(96)),
108            Col::White => self.s.push_str(f!(97)),
109        }
110        self.last_col = col;
111        self
112    }
113
114    pub fn bg(mut self, col: Col) -> Self {
115        match col {
116            Col::Black => self.s.push_str(f!(40)),
117            Col::Red => self.s.push_str(f!(41)),
118            Col::Green => self.s.push_str(f!(42)),
119            Col::Yellow => self.s.push_str(f!(43)),
120            Col::Blue => self.s.push_str(f!(44)),
121            Col::Purple => self.s.push_str(f!(45)),
122            Col::DarkCyan => self.s.push_str(f!(46)),
123            Col::Grey => self.s.push_str(f!(47)),
124            Col::DarkGrey => self.s.push_str(f!(100)),
125            Col::BrightRed => self.s.push_str(f!(101)),
126            Col::Lime => self.s.push_str(f!(102)),
127            Col::BrightYellow => self.s.push_str(f!(103)),
128            Col::BrightBlue => self.s.push_str(f!(104)),
129            Col::Magenta => self.s.push_str(f!(105)),
130            Col::Cyan => self.s.push_str(f!(106)),
131            Col::White => self.s.push_str(f!(107)),
132        }
133        self.last_bg = col;
134        self
135    }
136
137    pub fn revert_styles(self, fmt: Fmt, col: Col, bg: Col) -> Self {
138        self.col(col).bg(bg).fmt(fmt)
139    }
140
141    pub fn fmt_for(self, fmt: Fmt, text: &str) -> Self {
142        let f = self.last_fmt;
143        let c = self.last_col;
144        let b = self.last_bg;
145        self.fmt(fmt).text(text).revert_styles(f, c, b)
146    }
147
148    pub fn fmt_for_ln(self, fmt: Fmt, text: &str) -> Self {
149        self.fmt_for(fmt, text).ln()
150    }
151
152    pub fn col_for(self, col: Col, text: &str) -> Self {
153        let f = self.last_fmt;
154        let c = self.last_col;
155        let b = self.last_bg;
156        self.col(col).text(text).revert_styles(f, c, b)
157    }
158
159    pub fn col_for_ln(self, col: Col, text: &str) -> Self {
160        self.col_for(col, text).ln()
161    }
162
163    pub fn bg_for(self, col: Col, text: &str) -> Self {
164        let f = self.last_fmt;
165        let c = self.last_col;
166        let b = self.last_bg;
167        self.bg(col).text(text).revert_styles(f, c, b)
168    }
169
170    pub fn bg_for_ln(self, col: Col, text: &str) -> Self {
171        self.bg_for(col, text).ln()
172    }
173
174    pub fn all_for(self, fmt: Fmt, col: Col, bg: Col, text: &str) -> Self {
175        let f = self.last_fmt;
176        let c = self.last_col;
177        let b = self.last_bg;
178        self.col(col)
179            .bg(bg)
180            .fmt(fmt)
181            .text(text)
182            .revert_styles(f, c, b)
183    }
184
185    pub fn all_for_ln(self, fmt: Fmt, col: Col, bg: Col, text: &str) -> Self {
186        self.all_for(fmt, col, bg, text).ln()
187    }
188
189    pub fn flush(self) {
190        print!("{}", self.def().s);
191        std::io::stdout().flush().unwrap();
192    }
193}
194
195impl Display for Printer {
196    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197        write!(f, "{}", self.s)
198    }
199}