term_tools/lib.rs
1//! # Term_Tools: Rich API for Colorizing Terminal
2//!
3//! term_tools is a Rust library that provides a rich API for colorizing terminal output.
4//! It allows you to create styled text strings with various colors, effects, and formatters.
5
6mod ansi_code;
7mod styles;
8
9// =======================================================================
10use crate::{
11 ansi_code::ANSIEscapeCode,
12 styles::{
13 basic_color,
14 formatter,
15 paint_type::PaintType,
16 palette::PaletteColor,
17 rgb::Rgb,
18 Styles,
19 },
20};
21
22// =======================================================================
23
24/// Creates a styled text string with the given text and styles.
25///
26/// This function returns a `StyledText` object that can be customized with various styles,
27/// colors, and effects. The resulting styled text can be printed or used in other contexts.
28///
29/// # Examples
30///
31/// ```
32/// use term_tools::styled;
33///
34/// let txt = styled("Happy Day!")
35/// .rgb(204, 182, 122)
36/// .italic()
37/// .rapid_blink()
38/// .bg()
39/// .black()
40/// .fg()
41/// .paint();
42/// println!("{txt}");
43/// ```
44///
45/// # Styles
46///
47/// The following styles can be applied to the text:
48///
49/// * `rgb(r, g, b)`: Sets the text color to the given RGB values.
50/// * `italic()`: Sets the text to italic.
51/// * `rapid_blink()`: Sets the text to rapidly blink.
52/// * `bg()`: Sets the background color.
53/// * `fg()`: Sets the foreground color.
54/// * basic colors like : `red`,`black` and etc.
55///
56/// # Colors
57///
58/// The following colors can be used with the `rgb` method:
59///
60/// * `rgb(r, g, b)`: Sets the color to the given RGB values.
61///
62/// # Effects
63///
64/// The following effects can be applied to the text:
65///
66/// * `rapid_blink()`: Sets the text to rapidly blink.
67///
68/// # Returns
69///
70/// A `StyledText` object that can be printed or used in other contexts.
71pub fn styled(text: &str) -> StyledText {
72 StyledText::new(text.to_string())
73}
74
75/// A struct representing a styled text string.
76pub struct StyledText {
77 text: String,
78 start_styles: Vec<Styles>,
79}
80
81impl StyledText {
82 /// Creates a new `StyledText` object with the given text.
83 fn new(text: String) -> Self {
84 StyledText {
85 text,
86 start_styles: vec![],
87 }
88 }
89
90 /// Paints the styled text string with the given styles.
91 ///
92 /// This method returns a string representing the styled text.
93 pub fn paint(&mut self) -> String {
94 let mut default_paint_type = PaintType::FG;
95
96 let start_codes_list: Vec<String> = self.start_styles
97 .iter()
98 .rev()
99 .filter_map(|s| {
100 if let Styles::StylePaintType(p) = s {
101 default_paint_type = p.clone();
102 return None;
103 }
104 let t = s.make_styles(Some(&default_paint_type));
105 Some(ANSIEscapeCode::new(t.as_str()).code())
106 })
107 .collect::<Vec<_>>()
108 .into_iter()
109 .rev()
110 .collect();
111 let start_codes = start_codes_list.join("");
112 let end_codes = ANSIEscapeCode::new(
113 &formatter::RESET.make_styles(Some(&default_paint_type))
114 ).code();
115
116 format!("{}{}{}", start_codes, self.text, end_codes)
117 }
118
119 /// Sets the foreground color of the colors you have called.
120 ///
121 /// # Example:
122 /// ```
123 /// use term_tools::styled;
124 /// let styled_text = styled("How you doing?").black().fg().red().bg().paint();
125 /// ```
126 /// the colors before this method will paint as foreground!
127 /// so the black color will paint as foreground and red color paint
128 /// as background color
129 /// **if the one `fg` call, all the colors will paint as foreground no matter there is before or after `fg`**
130 pub fn fg(&mut self) -> &mut Self {
131 self.start_styles.push(Styles::StylePaintType(PaintType::FG));
132 self
133 }
134
135 /// Sets the background color of the colors you have called.
136 ///
137 /// # Example:
138 /// ```
139 /// use term_tools::styled;
140 /// let styled_text = styled("I'm feel Happy").bright_cyan().bg().blue().fg().paint();
141 /// ```
142 /// the colors before this method will paint as background!
143 /// so the bright_cyan color will paint as background and blue color paint
144 /// as foreground color
145 /// **if the one `bg` call, all the colors will paint as background no matter there is before or after `bg`**
146 pub fn bg(&mut self) -> &mut Self {
147 self.start_styles.push(Styles::StylePaintType(PaintType::BG));
148 self
149 }
150
151 // Colors
152
153 /// Sets the `rgb` color to the input text.
154 ///
155 /// # Example:
156 /// ```
157 /// use term_tools::styled;
158 /// let styled_text = styled("Our life is what our thoughts make it.").rgb(48,118,230).paint();
159 /// ```
160 pub fn rgb(&mut self, r: u8, g: u8, b: u8) -> &mut Self {
161 self.start_styles.push(Styles::StyleRgb(Rgb { r, g, b }));
162 self
163 }
164
165 /// Sets the `palette` color to the input text.
166 ///
167 /// # Example:
168 /// ```
169 /// use term_tools::styled;
170 /// let styled_text = styled("If it is not right, do not do it. If it is not true, do not say it.").palette(132).paint();
171 /// ```
172 ///
173 /// the index should be 8 bit color between 0 to 255.
174 pub fn palette(&mut self, index: u8) -> &mut Self {
175 self.start_styles.push(Styles::StylePaletteColor(PaletteColor { index }));
176 self
177 }
178
179 /// Sets the `black` color to the input text.
180 ///
181 /// # Example:
182 /// ```
183 /// use term_tools::styled;
184 /// let styled_text = styled("The best revenge is to not be like your enemies.").black().paint();
185 /// ```
186 pub fn black(&mut self) -> &mut Self {
187 self.start_styles.push(basic_color::BLACK);
188 self
189 }
190
191 /// Sets the `red` color to the input text.
192 ///
193 /// # Example:
194 /// ```
195 /// use term_tools::styled;
196 /// let styled_text = styled("To love only what happens, what was destined. No greater harmony.").red().paint();
197 /// ```
198 pub fn red(&mut self) -> &mut Self {
199 self.start_styles.push(basic_color::RED);
200 self
201 }
202
203 /// Sets the `green` color to the input text.
204 ///
205 /// # Example:
206 /// ```
207 /// use term_tools::styled;
208 /// let styled_text = styled("Everything we hear is opinion, not a fact. Everything we see is a perspective, not the truth.").green().paint();
209 /// ```
210 pub fn green(&mut self) -> &mut Self {
211 self.start_styles.push(basic_color::GREEN);
212 self
213 }
214
215 /// Sets the `yellow` color to the input text.
216 ///
217 /// # Example:
218 /// ```
219 /// use term_tools::styled;
220 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").yellow().paint();
221 /// ```
222 pub fn yellow(&mut self) -> &mut Self {
223 self.start_styles.push(basic_color::YELLOW);
224 self
225 }
226
227 /// Sets the `blue` color to the input text.
228 ///
229 /// # Example:
230 /// ```
231 /// use term_tools::styled;
232 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").blue().paint();
233 /// ```
234 pub fn blue(&mut self) -> &mut Self {
235 self.start_styles.push(basic_color::BLUE);
236 self
237 }
238
239 /// Sets the `magenta` color to the input text.
240 ///
241 /// # Example:
242 /// ```
243 /// use term_tools::styled;
244 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").magenta().paint();
245 /// ```
246 pub fn magenta(&mut self) -> &mut Self {
247 self.start_styles.push(basic_color::MAGENTA);
248 self
249 }
250
251 /// Sets the `cyan` color to the input text.
252 ///
253 /// # Example:
254 /// ```
255 /// use term_tools::styled;
256 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").cyan().paint();
257 /// ```
258 pub fn cyan(&mut self) -> &mut Self {
259 self.start_styles.push(basic_color::CYAN);
260 self
261 }
262
263 /// Sets the `white` color to the input text.
264 ///
265 /// # Example:
266 /// ```
267 /// use term_tools::styled;
268 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").white().paint();
269 /// ```
270 pub fn white(&mut self) -> &mut Self {
271 self.start_styles.push(basic_color::WHITE);
272 self
273 }
274
275 /// Sets the `gray` color to the input text.
276 ///
277 /// # Example:
278 /// ```
279 /// use term_tools::styled;
280 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").gray().paint();
281 /// ```
282 pub fn gray(&mut self) -> &mut Self {
283 self.start_styles.push(basic_color::GRAY);
284 self
285 }
286
287 /// Sets the `bright_red` color to the input text.
288 ///
289 /// # Example:
290 /// ```
291 /// use term_tools::styled;
292 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_red().paint();
293 /// ```
294 pub fn bright_red(&mut self) -> &mut Self {
295 self.start_styles.push(basic_color::BRIGHT_RED);
296 self
297 }
298
299 /// Sets the `bright_green` color to the input text.
300 ///
301 /// # Example:
302 /// ```
303 /// use term_tools::styled;
304 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_green().paint();
305 /// ```
306 pub fn bright_green(&mut self) -> &mut Self {
307 self.start_styles.push(basic_color::BRIGHT_GREEN);
308 self
309 }
310
311 /// Sets the `bright_yellow` color to the input text.
312 ///
313 /// # Example:
314 /// ```
315 /// use term_tools::styled;
316 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_yellow().paint();
317 /// ```
318 pub fn bright_yellow(&mut self) -> &mut Self {
319 self.start_styles.push(basic_color::BRIGHT_YELLOW);
320 self
321 }
322
323 /// Sets the `bright_blue` color to the input text.
324 ///
325 /// # Example:
326 /// ```
327 /// use term_tools::styled;
328 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_blue().paint();
329 /// ```
330 pub fn bright_blue(&mut self) -> &mut Self {
331 self.start_styles.push(basic_color::BRIGHT_BLUE);
332 self
333 }
334
335 /// Sets the `bright_magenta` color to the input text.
336 ///
337 /// # Example:
338 /// ```
339 /// use term_tools::styled;
340 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_magenta().paint();
341 /// ```
342 /// use term_tools::styled;
343 pub fn bright_magenta(&mut self) -> &mut Self {
344 self.start_styles.push(basic_color::BRIGHT_MAGENTA);
345 self
346 }
347
348 /// Sets the `bright_cyan` color to the input text.
349 ///
350 /// # Example:
351 /// ```
352 /// use term_tools::styled;
353 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_cyan().paint();
354 /// ```
355 pub fn bright_cyan(&mut self) -> &mut Self {
356 self.start_styles.push(basic_color::BRIGHT_CYAN);
357 self
358 }
359
360 /// Sets the `bright_white` color to the input text.
361 ///
362 /// # Example:
363 /// ```
364 /// use term_tools::styled;
365 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_white().paint();
366 /// ```
367 pub fn bright_white(&mut self) -> &mut Self {
368 self.start_styles.push(basic_color::BRIGHT_WHITE);
369 self
370 }
371
372 // Formatters
373
374 /// Sets the `reset` effect to the input text.
375 ///
376 /// # Example:
377 /// ```
378 /// use term_tools::styled;
379 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").red().reset().paint();
380 /// ```
381 /// ** this will reset all the effects, colors and formatters that are called before this**
382 /// so in the top example the red color will never applied to the input text
383 pub fn reset(&mut self) -> &mut Self {
384 self.start_styles.push(formatter::RESET);
385 self
386 }
387
388 /// Sets the `bold` format to the input text.
389 ///
390 /// # Example:
391 /// ```
392 /// use term_tools::styled;
393 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bold().paint();
394 /// ```
395 pub fn bold(&mut self) -> &mut Self {
396 self.start_styles.push(formatter::BOLD);
397 self
398 }
399
400 /// Sets the `faint` format to the input text.
401 ///
402 /// # Example:
403 /// ```
404 /// use term_tools::styled;
405 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").faint().paint();
406 /// ```
407 pub fn faint(&mut self) -> &mut Self {
408 self.start_styles.push(formatter::FAINT);
409 self
410 }
411
412 /// Sets the `italic` format to the input text.
413 ///
414 /// # Example:
415 /// ```
416 /// use term_tools::styled;
417 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").italic().paint();
418 /// ```
419 pub fn italic(&mut self) -> &mut Self {
420 self.start_styles.push(formatter::ITALIC);
421 self
422 }
423
424 /// Sets the `underline` format to the input text.
425 ///
426 /// # Example:
427 /// ```
428 /// use term_tools::styled;
429 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").underline().paint();
430 /// ```
431 pub fn underline(&mut self) -> &mut Self {
432 self.start_styles.push(formatter::UNDERLINE);
433 self
434 }
435
436 /// Sets the `slow_blink` effect to the input text.
437 ///
438 /// # Example:
439 /// ```
440 /// use term_tools::styled;
441 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").slow_blink().paint();
442 /// ```
443 ///
444 /// **base on the terminal you are using this could not be applied**
445 pub fn slow_blink(&mut self) -> &mut Self {
446 self.start_styles.push(formatter::SLOW_BLINK);
447 self
448 }
449
450 /// Sets the `rapid_blink` effect to the input text.
451 ///
452 /// # Example:
453 /// ```
454 /// use term_tools::styled;
455 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").rapid_blink().paint();
456 /// ```
457 ///
458 /// **base on the terminal you are using this could not be applied**
459 pub fn rapid_blink(&mut self) -> &mut Self {
460 self.start_styles.push(formatter::RAPID_BLINK);
461 self
462 }
463
464 /// Sets the `overline` effect to the input text.
465 ///
466 /// # Example:
467 /// ```
468 /// use term_tools::styled;
469 /// let styled_text = styled("The present is all we have to live in . . . or to lose.").overline().paint();
470 /// ```
471 pub fn overline(&mut self) -> &mut Self {
472 self.start_styles.push(formatter::OVERLINE);
473 self
474 }
475}