crossterm_style/lib.rs
1#![deny(unused_imports, unused_must_use)]
2
3//! # Style
4//!
5//! **The `crossterm_style` crate is deprecated and no longer maintained. The GitHub repository will
6//! be archived soon. All the code is being moved to the `crossterm`
7//! [crate](https://github.com/crossterm-rs/crossterm). You can learn more in
8//! the [Merge sub-crates to the crossterm crate](https://github.com/crossterm-rs/crossterm/issues/265)
9//! issue.**
10//!
11//! The `crossterm_style` crate provides a functionality to apply attributes and colors on your text.
12//!
13//! This documentation does not contain a lot of examples. The reason is that it's fairly
14//! obvious how to use this crate. Although, we do provide
15//! [examples](https://github.com/crossterm-rs/examples) repository
16//! to demonstrate the capabilities.
17//!
18//! ## Platform-specific Notes
19//!
20//! Not all features are supported on all terminals/platforms. You should always consult
21//! platform-specific notes of the following types:
22//!
23//! * [Color](enum.Color.html#platform-specific-notes)
24//! * [Attribute](enum.Attribute.html#platform-specific-notes)
25//!
26//! ## Examples
27//!
28//! ### Colors
29//!
30//! The command API:
31//!
32//! ```no_run
33//! use std::io::{stdout, Write};
34//!
35//! use crossterm_utils::{execute, Result, Output};
36//! use crossterm_style::{SetBg, SetFg, ResetColor, Color, Attribute};
37//!
38//! fn main() -> Result<()> {
39//! execute!(
40//! stdout(),
41//! // Blue foreground
42//! SetFg(Color::Blue),
43//! // Red background
44//! SetBg(Color::Red),
45//! Output("Styled text here.".to_string()),
46//! // Reset to default colors
47//! ResetColor
48//! )
49//! }
50//! ```
51//!
52//! The [`Colored`](enum.Colored.html) & [`Color`](enum.Color.html) enums:
53//!
54//! ```no_run
55//! use crossterm_style::{Colored, Color};
56//!
57//! println!("{} Red foreground", Colored::Fg(Color::Red));
58//! println!("{} Blue background", Colored::Bg(Color::Blue));
59//! ```
60//!
61//! The [`Colorize`](trait.Colorize.html) trait:
62//!
63//! ```no_run
64//! use crossterm_style::Colorize;
65//!
66//! println!("{}", "Red foreground color & blue background.".red().on_blue());
67//! ```
68//!
69//! ### Attributes
70//!
71//! The command API:
72//!
73//! ```no_run
74//! use std::io::{stdout, Write};
75//!
76//! use crossterm_utils::{execute, Result, Output};
77//! use crossterm_style::{SetAttr, Attribute};
78//!
79//! fn main() -> Result<()> {
80//! execute!(
81//! stdout(),
82//! // Set to bold
83//! SetAttr(Attribute::Bold),
84//! Output("Styled text here.".to_string()),
85//! // Reset all attributes
86//! SetAttr(Attribute::Reset)
87//! )
88//! }
89//! ```
90//!
91//! The [`Styler`](trait.Styler.html) trait:
92//!
93//! ```no_run
94//! use crossterm_style::Styler;
95//!
96//! println!("{}", "Bold".bold());
97//! println!("{}", "Underlined".underlined());
98//! println!("{}", "Negative".negative());
99//! ```
100//!
101//! The [`Attribute`](enum.Attribute.html) enum:
102//!
103//! ```no_run
104//! use crossterm_style::Attribute;
105//!
106//! println!(
107//! "{} Underlined {} No Underline",
108//! Attribute::Underlined,
109//! Attribute::NoUnderline
110//! );
111//! ```
112
113use std::env;
114use std::fmt::Display;
115
116#[cfg(windows)]
117use crossterm_utils::supports_ansi;
118#[doc(no_inline)]
119pub use crossterm_utils::{
120 execute, impl_display, queue, Command, ExecutableCommand, QueueableCommand, Result,
121};
122
123use style::ansi::{self, AnsiColor};
124#[cfg(windows)]
125use style::winapi::WinApiColor;
126use style::Style;
127
128pub use self::enums::{Attribute, Color, Colored};
129pub use self::objectstyle::ObjectStyle;
130pub use self::styledobject::StyledObject;
131pub use self::traits::{Colorize, Styler};
132
133#[macro_use]
134mod macros;
135mod enums;
136mod objectstyle;
137mod style;
138mod styledobject;
139mod traits;
140
141/// Creates a `StyledObject`.
142///
143/// This could be used to style any type that implements `Display` with colors and text attributes.
144///
145/// See [`StyledObject`](struct.StyledObject.html) for more info.
146///
147/// # Examples
148///
149/// ```no_run
150/// use crossterm_style::{style, Color};
151///
152/// let styled_object = style("Blue colored text on yellow background")
153/// .with(Color::Blue)
154/// .on(Color::Yellow);
155///
156/// println!("{}", styled_object);
157/// ```
158pub fn style<'a, D: 'a>(val: D) -> StyledObject<D>
159where
160 D: Display + Clone,
161{
162 ObjectStyle::new().apply_to(val)
163}
164
165impl Colorize<&'static str> for &'static str {
166 // foreground colors
167 def_str_color!(fg_color: black => Color::Black);
168 def_str_color!(fg_color: dark_grey => Color::DarkGrey);
169 def_str_color!(fg_color: red => Color::Red);
170 def_str_color!(fg_color: dark_red => Color::DarkRed);
171 def_str_color!(fg_color: green => Color::Green);
172 def_str_color!(fg_color: dark_green => Color::DarkGreen);
173 def_str_color!(fg_color: yellow => Color::Yellow);
174 def_str_color!(fg_color: dark_yellow => Color::DarkYellow);
175 def_str_color!(fg_color: blue => Color::Blue);
176 def_str_color!(fg_color: dark_blue => Color::DarkBlue);
177 def_str_color!(fg_color: magenta => Color::Magenta);
178 def_str_color!(fg_color: dark_magenta => Color::DarkMagenta);
179 def_str_color!(fg_color: cyan => Color::Cyan);
180 def_str_color!(fg_color: dark_cyan => Color::DarkCyan);
181 def_str_color!(fg_color: white => Color::White);
182 def_str_color!(fg_color: grey => Color::Grey);
183
184 // background colors
185 def_str_color!(bg_color: on_black => Color::Black);
186 def_str_color!(bg_color: on_dark_grey => Color::DarkGrey);
187 def_str_color!(bg_color: on_red => Color::Red);
188 def_str_color!(bg_color: on_dark_red => Color::DarkRed);
189 def_str_color!(bg_color: on_green => Color::Green);
190 def_str_color!(bg_color: on_dark_green => Color::DarkGreen);
191 def_str_color!(bg_color: on_yellow => Color::Yellow);
192 def_str_color!(bg_color: on_dark_yellow => Color::DarkYellow);
193 def_str_color!(bg_color: on_blue => Color::Blue);
194 def_str_color!(bg_color: on_dark_blue => Color::DarkBlue);
195 def_str_color!(bg_color: on_magenta => Color::Magenta);
196 def_str_color!(bg_color: on_dark_magenta => Color::DarkMagenta);
197 def_str_color!(bg_color: on_cyan => Color::Cyan);
198 def_str_color!(bg_color: on_dark_cyan => Color::DarkCyan);
199 def_str_color!(bg_color: on_white => Color::White);
200 def_str_color!(bg_color: on_grey => Color::Grey);
201}
202
203impl Styler<&'static str> for &'static str {
204 def_str_attr!(reset => Attribute::Reset);
205 def_str_attr!(bold => Attribute::Bold);
206 def_str_attr!(underlined => Attribute::Underlined);
207 def_str_attr!(reverse => Attribute::Reverse);
208 def_str_attr!(dim => Attribute::Dim);
209 def_str_attr!(italic => Attribute::Italic);
210 def_str_attr!(negative => Attribute::Reverse);
211 def_str_attr!(slow_blink => Attribute::SlowBlink);
212 def_str_attr!(rapid_blink => Attribute::RapidBlink);
213 def_str_attr!(hidden => Attribute::Hidden);
214 def_str_attr!(crossed_out => Attribute::CrossedOut);
215}
216
217/// A terminal color.
218///
219/// # Examples
220///
221/// Basic usage:
222///
223/// ```no_run
224/// // You can replace the following line with `use crossterm::TerminalColor;`
225/// // if you're using the `crossterm` crate with the `style` feature enabled.
226/// use crossterm_style::{Result, TerminalColor, Color};
227///
228/// fn main() -> Result<()> {
229/// let color = TerminalColor::new();
230/// // Set foreground color
231/// color.set_fg(Color::Blue)?;
232/// // Set background color
233/// color.set_bg(Color::Red)?;
234/// // Reset to the default colors
235/// color.reset()
236/// }
237/// ```
238pub struct TerminalColor {
239 #[cfg(windows)]
240 color: Box<(dyn Style + Sync + Send)>,
241 #[cfg(unix)]
242 color: AnsiColor,
243}
244
245impl TerminalColor {
246 /// Creates a new `TerminalColor`.
247 pub fn new() -> TerminalColor {
248 #[cfg(windows)]
249 let color = if supports_ansi() {
250 Box::from(AnsiColor::new()) as Box<(dyn Style + Sync + Send)>
251 } else {
252 WinApiColor::new() as Box<(dyn Style + Sync + Send)>
253 };
254
255 #[cfg(unix)]
256 let color = AnsiColor::new();
257
258 TerminalColor { color }
259 }
260
261 /// Sets the foreground color.
262 pub fn set_fg(&self, color: Color) -> Result<()> {
263 self.color.set_fg(color)
264 }
265
266 /// Sets the background color.
267 pub fn set_bg(&self, color: Color) -> Result<()> {
268 self.color.set_bg(color)
269 }
270
271 /// Resets the terminal colors and attributes to the default ones.
272 pub fn reset(&self) -> Result<()> {
273 self.color.reset()
274 }
275
276 /// Returns available color count.
277 ///
278 /// # Notes
279 ///
280 /// This does not always provide a good result.
281 pub fn available_color_count(&self) -> u16 {
282 env::var("TERM")
283 .map(|x| if x.contains("256color") { 256 } else { 8 })
284 .unwrap_or(8)
285 }
286}
287
288/// Creates a new `TerminalColor`.
289///
290/// # Examples
291///
292/// Basic usage:
293///
294/// ```no_run
295/// use crossterm_style::{color, Color, Result};
296///
297/// fn main() -> Result<()> {
298/// let color = color();
299/// // Set foreground color
300/// color.set_fg(Color::Blue)?;
301/// // Set background color
302/// color.set_bg(Color::Red)?;
303/// // Reset to the default colors
304/// color.reset()
305/// }
306/// ```
307pub fn color() -> TerminalColor {
308 TerminalColor::new()
309}
310
311/// A command to set the foreground color.
312///
313/// See [`Color`](enum.Color.html) for more info.
314///
315/// # Notes
316///
317/// Commands must be executed/queued for execution otherwise they do nothing.
318pub struct SetFg(pub Color);
319
320impl Command for SetFg {
321 type AnsiType = String;
322
323 fn ansi_code(&self) -> Self::AnsiType {
324 ansi::set_fg_csi_sequence(self.0)
325 }
326
327 #[cfg(windows)]
328 fn execute_winapi(&self) -> Result<()> {
329 WinApiColor::new().set_fg(self.0)
330 }
331}
332
333/// A command to set the background color.
334///
335/// See [`Color`](enum.Color.html) for more info.
336///
337/// # Notes
338///
339/// Commands must be executed/queued for execution otherwise they do nothing.
340pub struct SetBg(pub Color);
341
342impl Command for SetBg {
343 type AnsiType = String;
344
345 fn ansi_code(&self) -> Self::AnsiType {
346 ansi::set_bg_csi_sequence(self.0)
347 }
348
349 #[cfg(windows)]
350 fn execute_winapi(&self) -> Result<()> {
351 WinApiColor::new().set_bg(self.0)
352 }
353}
354
355/// A command to set the text attribute.
356///
357/// See [`Attribute`](enum.Attribute.html) for more info.
358///
359/// # Notes
360///
361/// Commands must be executed/queued for execution otherwise they do nothing.
362pub struct SetAttr(pub Attribute);
363
364impl Command for SetAttr {
365 type AnsiType = String;
366
367 fn ansi_code(&self) -> Self::AnsiType {
368 ansi::set_attr_csi_sequence(self.0)
369 }
370
371 #[cfg(windows)]
372 fn execute_winapi(&self) -> Result<()> {
373 // attributes are not supported by WinAPI.
374 Ok(())
375 }
376}
377
378/// A command to print the styled object.
379///
380/// See [`StyledObject`](struct.StyledObject.html) for more info.
381///
382/// # Notes
383///
384/// Commands must be executed/queued for execution otherwise they do nothing.
385pub struct PrintStyledFont<D: Display + Clone>(pub StyledObject<D>);
386
387impl<D> Command for PrintStyledFont<D>
388where
389 D: Display + Clone,
390{
391 type AnsiType = StyledObject<D>;
392
393 fn ansi_code(&self) -> Self::AnsiType {
394 self.0.clone()
395 }
396
397 #[cfg(windows)]
398 fn execute_winapi(&self) -> Result<()> {
399 Ok(())
400 }
401}
402
403/// A command to reset the colors back to default ones.
404///
405/// # Notes
406///
407/// Commands must be executed/queued for execution otherwise they do nothing.
408pub struct ResetColor;
409
410impl Command for ResetColor {
411 type AnsiType = String;
412
413 fn ansi_code(&self) -> Self::AnsiType {
414 ansi::RESET_CSI_SEQUENCE.to_string()
415 }
416
417 #[cfg(windows)]
418 fn execute_winapi(&self) -> Result<()> {
419 WinApiColor::new().reset()
420 }
421}
422
423impl_display!(for SetFg);
424impl_display!(for SetBg);
425impl_display!(for SetAttr);
426impl_display!(for PrintStyledFont<String>);
427impl_display!(for PrintStyledFont<&'static str>);
428impl_display!(for ResetColor);