colorful_console/
lib.rs

1//! A crate to make using colored text in the terminal easy
2//! # Example
3//! ```rust
4//! use colorful_console::*;
5//!
6//! fn main() {
7//!   console::log("Starting", Color::Reset);
8//!   console::warn(&*format!("Could {} instantiate", color_wrap("not", Color::Red)), Color::Reset);
9//!   console::error("Something went wrong, restarting soon", Color::Reset);
10//!   clear_terminal();
11//! }
12//! ```
13
14type ColoredString = String;
15type ColorCode = Option<u8>;
16
17pub trait LoggableResult<T> {
18  fn catch_error(self, msg: &str, color: Color) -> T;
19}
20
21impl<T, E: std::fmt::Debug> LoggableResult<T> for Result<T, E> {
22  /// A method to catch errors with ```console::error()``` instead of ```.expect()```
23  /// In your message that you specify, you can use `{error}` and it will be replaced by the actual error message
24  /// # Example
25  /// ```rust
26  /// use colorful_console::*;
27  /// use std::fs::File;
28  /// 
29  /// fn main() {
30  ///   File::open("test.txt").catch_error("An error occurred: {error}", Color::Red);
31  ///  }
32  /// ```
33  fn catch_error(self, msg: &str, color: Color) -> T {
34    match self {
35      Ok(val) => val,  // If Ok, return the value
36      Err(err) => {
37        let msg = msg.replace("{error}", &*format!("{:#?}", err));
38        console::error(&*msg, color);  // Log the error
39        std::process::exit(1);  // Exit the program
40      }
41    }
42  }
43}
44
45pub enum Color {
46  Black,
47  Maroon,
48  Green,
49  Olive,
50  Navy,
51  Purple,
52  Teal,
53  Silver,
54  Grey,
55  Red,
56  Lime,
57  Yellow,
58  Blue,
59  Fuchsia,
60  Aqua,
61  White,
62  Reset
63}
64
65impl Color {
66  fn to_color_code(&self) -> ColorCode {
67    match self {
68      Color::Black => Some(0),
69      Color::Maroon => Some(1),
70      Color::Green => Some(2),
71      Color::Olive => Some(3),
72      Color::Navy => Some(4),
73      Color::Purple => Some(5),
74      Color::Teal => Some(6),
75      Color::Silver => Some(7),
76      Color::Grey => Some(8),
77      Color::Red => Some(9),
78      Color::Lime => Some(10),
79      Color::Yellow => Some(11),
80      Color::Blue => Some(12),
81      Color::Fuchsia => Some(13),
82      Color::Aqua => Some(14),
83      Color::White => Some(15),
84      Color::Reset => None
85    }
86  }
87}
88
89enum Level {
90  Log,
91  Warn,
92  Error
93}
94
95fn log_level(level: Level, text: &str, color_code: Color) -> () {
96  let level_color: Color = match level {
97    Level::Log => Color::Lime,
98    Level::Warn => Color::Yellow,
99    Level::Error => Color::Red,
100  };
101
102  let level_prefix: String = match level {
103    Level::Log => String::from("[LOG]  "),
104    Level::Warn => String::from("[WARN] "),
105    Level::Error => String::from("[ERROR]"),
106  };
107
108  let reset = "\x1b[0m";
109  let color = match color_code.to_color_code() {
110    Some(color_code) => format!("\x1b[38;5;{color_code}m"),
111    None => format!("{reset}")
112  };
113
114  let colored_text = format!("{color}{text}{reset}");
115  let date_time = chrono::Local::now().format("%d/%m/%Y, %H:%M:%S").to_string();
116  let prefix = format!("{} {}", color_wrap(&*level_prefix, level_color), color_wrap(&*date_time, Color::Silver));
117
118  let output = format!("{prefix} {colored_text}");
119
120  println!("{output}")
121}
122
123pub mod console {
124  use crate::{log_level, Color, Level};
125
126  /// A function made for logging information to the console.
127  /// Not meant to print stuff like "Hello world!".
128  pub fn log(text: &str, color_code: Color) {
129    log_level(Level::Log, text, color_code);
130  }
131
132  /// A function made for warning the user of something that went wrong.
133  /// Not meant to print stuff like "Hello world!".
134  pub fn warn(text: &str, color_code: Color) {
135    log_level(Level::Warn, text, color_code);
136  }
137
138  /// A function made to show an error in the console.
139  /// Not meant to print stuff like "Hello world!".
140  pub fn error(text: &str, color_code: Color) {
141    log_level(Level::Error, text, color_code);
142  }
143}
144
145/// A function that puts the correct ascii-escape characters around a string so that the string is colored in the specified color.
146/// # Example
147/// ```rust
148/// use colorful_console::{color_wrap, Color};
149/// let text = color_wrap("Hello world!", Color::Fuchsia);
150/// println!("{}" ,text)
151/// ```
152pub fn color_wrap(text: &str, color_code: Color) -> ColoredString {
153  let reset = "\x1b[0m";
154  let color: String;
155  match color_code.to_color_code() {
156    Some(color_code) => {color = format!("\x1b[38;5;{}m", color_code);}
157    None => {color = format!("{reset}");}
158  }
159  format!("{color}{text}{reset}")
160}
161
162/// Clears the terminal screen
163pub fn clear_terminal() {
164  print!("\x1B[2J\x1B[1;1H");
165}