colorize/lib.rs
1//! A set of Rust macros to assist in turning text into colors for printing on the terminal.
2//! ## Usage
3//!
4//! `colorize!` takes a series of inputs, with or without tokens, and converts the inputs into a `String` with ANSI escape sequences added in.
5//!
6//! The returned `String` is primarily useful for printing out to a terminal which is capable of showing color.
7//! However, if all you want to do is print, and want to cut out the extra code, use [`print_color`] instead.
8//!
9//! ## Valid inputs
10//! `colorize!` uses the same formatting style as [`format!`](std::format!) so it follows the same
11//! argument rules.
12//!
13//! ```
14//! # use colorize_proc_macro as colorize;
15//! use std::path::PathBuf;
16//! use colorize::colorize;
17//!
18//! let user_path = PathBuf::from("/home/color/my_new_file.txt");
19//! let pretty_path = colorize!("{:?}", Fgu->user_path.clone());
20//!
21//! assert_eq!(
22//! String::from("\x1b[32;4m\"/home/color/my_new_file.txt\"\x1b[0m"),
23//! pretty_path
24//! );
25//! ```
26//!
27//! ## Tokens
28//! Tokens can change color or font styling depending on their order and usage.
29//!
30//! #### Styling
31//! 1. b -> bold
32//! 2. u -> underline
33//! 3. i -> italic
34//!
35//! #### Color
36//! Color tokens start with an `F` (for foreground) or `B` (for background)
37//!
38//! 1. Fb/Bb -> blue
39//! 2. Fr/Br -> red
40//! 3. Fg/Bg -> green
41//! 4. Fy/By -> yellow
42//! 5. Fm/By -> magenta
43//! 6. Fc/Bc -> cyan
44//! 7. Fw/Bw -> white
45//! 8. Fk/Bk -> black
46//!
47//! #### Special Newline Token
48//! If you want to add a newline within the string, include a `N` token at the start
49//! of the word(s) you wish to be on the newline. This is the same as just adding '\n' to the
50//! string, so it's up to you to use it or not.
51//!
52//!
53//! Example -
54//! ```
55//! # use colorize_proc_macro as colorize;
56//! use colorize::colorize;
57//!
58//! let color_string = colorize!(
59//! "{} {}",
60//! b->"Hello", // First line
61//! Nb->"world, it's me!" // "world..." will be on the new line
62//! );
63//!
64//! let same_color_string = colorize!(
65//! "{} \n{}",
66//! b->"Hello",
67//! b->"world, it's me!"
68//! );
69//!
70//! assert_eq!(color_string, same_color_string);
71//! ```
72//!
73//! #### Format Multiple Inputs
74//! You also have the ability to apply a token to multiple inputs by using `=>` at the beginning of the call.
75//!
76//! ```
77//! # use colorize_proc_macro as colorize;
78//! use colorize::colorize;
79//!
80//! let color_string = colorize!("{} {}", b => Fg->"Hello", By->"world");
81//! ```
82//! In the above example, "Hello" will have a green foreground, and "world" will have a yellow background. The preceeding `b =>` applies bold formatting to both.
83//!
84//! ### Examples
85//! ```
86//! # use colorize_proc_macro as colorize;
87//! use colorize::colorize;
88//!
89//! // Returns "Hello" in bold green
90//! let color_string = colorize!("{}", Fgb->"Hello");
91//! assert_eq!(String::from("\x1b[32;1mHello\x1b[0m"), color_string);
92//!
93//! // Returns "Hello" in italic blue and "World" underlined in magenta
94//! // ", it's me" will be unformatted
95//! let color_string = colorize!("{} {} {}", iFb->"Hello", Fmu->"world", ", it's me!");
96//! assert_eq!(String::from("\x1b[3;34mHello\x1b[0m \x1b[35;4mworld\x1b[0m , it's me!"), color_string);
97//! ```
98
99#[doc(hidden)]
100#[allow(unused)]
101pub use paste::paste;
102
103pub use colorize_proc_macro::colorize;
104
105/// `println!` using the [`colorize!`] macro
106///
107///
108/// See [`colorize!`] for more details
109///
110/// ## Usage
111/// ```
112/// use colorize::print_color;
113///
114/// // Will println to the console with "Hello" bold and green, world will be unformatted
115/// print_color!("{} {}", Fgb->"Hello", "world")
116/// ```
117#[macro_export]
118macro_rules! print_color {
119 () => (println!(""));
120 ( $($any:tt)* ) => ( println!("{}", $crate::colorize!($($any)*)) );
121}
122
123#[cfg(test)]
124mod tests {
125 use std::str::FromStr;
126
127 use super::{colorize, print_color};
128
129 #[test]
130 fn test_colorize() {
131 let col_str = colorize!("{} {} {} {} {}", Fgb->"hello again", N->"hello", "and", BrFb->"goodbye", b->"again" );
132 assert_eq!(
133 String::from("\x1b[32;1mhello again\x1b[0m \n\x1b[mhello\x1b[0m and \x1b[41;34mgoodbye\x1b[0m \x1b[1magain\x1b[0m"),
134 col_str
135 )
136 }
137
138 #[test]
139 fn test_colorize_all() {
140 let col_str = colorize!("{} {} {}", b => Fg->"One", "two", Fb->"three");
141
142 assert_eq!(
143 String::from("\x1b[1;32mOne\x1b[0m \x1b[1mtwo\x1b[0m \x1b[1;34mthree\x1b[0m"),
144 col_str
145 )
146 }
147
148 #[test]
149 fn test_debug() {
150 use std::path::PathBuf;
151 let path = PathBuf::from_str("some").unwrap();
152 let col = colorize!("{} {:?} {}", b->"Moving", Fgb->path.clone(), b->"to");
153 assert_eq!(
154 String::from("\x1b[1mMoving\x1b[0m \x1b[32;1m\"some\"\x1b[0m \x1b[1mto\x1b[0m"),
155 col
156 );
157
158 print_color!("{} {:?} {} {:?}", b => "Moving", Fg->path, "to", Fg->PathBuf::from("other"))
159 }
160}