1 | //! # Style
|
2 | //!
|
3 | //! The `style` module provides a functionality to apply attributes and colors on your text.
|
4 | //!
|
5 | //! This documentation does not contain a lot of examples. The reason is that it's fairly
|
6 | //! obvious how to use this crate. Although, we do provide
|
7 | //! [examples](https://github.com/crossterm-rs/crossterm/tree/master/examples) repository
|
8 | //! to demonstrate the capabilities.
|
9 | //!
|
10 | //! ## Platform-specific Notes
|
11 | //!
|
12 | //! Not all features are supported on all terminals/platforms. You should always consult
|
13 | //! platform-specific notes of the following types:
|
14 | //!
|
15 | //! * [Color](enum.Color.html#platform-specific-notes)
|
16 | //! * [Attribute](enum.Attribute.html#platform-specific-notes)
|
17 | //!
|
18 | //! ## Examples
|
19 | //!
|
20 | //! A few examples of how to use the style module.
|
21 | //!
|
22 | //! ### Colors
|
23 | //!
|
24 | //! How to change the terminal text color.
|
25 | //!
|
26 | //! Command API:
|
27 | //!
|
28 | //! Using the Command API to color text.
|
29 | //!
|
30 | //! ```no_run
|
31 | //! use std::io::{self, Write};
|
32 | //! use crossterm::execute;
|
33 | //! use crossterm::style::{Print, SetForegroundColor, SetBackgroundColor, ResetColor, Color, Attribute};
|
34 | //!
|
35 | //! fn main() -> io::Result<()> {
|
36 | //! execute!(
|
37 | //! io::stdout(),
|
38 | //! // Blue foreground
|
39 | //! SetForegroundColor(Color::Blue),
|
40 | //! // Red background
|
41 | //! SetBackgroundColor(Color::Red),
|
42 | //! // Print text
|
43 | //! Print("Blue text on Red." .to_string()),
|
44 | //! // Reset to default colors
|
45 | //! ResetColor
|
46 | //! )
|
47 | //! }
|
48 | //! ```
|
49 | //!
|
50 | //! Functions:
|
51 | //!
|
52 | //! Using functions from [`Stylize`](crate::style::Stylize) on a `String` or `&'static str` to color
|
53 | //! it.
|
54 | //!
|
55 | //! ```no_run
|
56 | //! use crossterm::style::Stylize;
|
57 | //!
|
58 | //! println!("{}" , "Red foreground color & blue background." .red().on_blue());
|
59 | //! ```
|
60 | //!
|
61 | //! ### Attributes
|
62 | //!
|
63 | //! How to apply terminal attributes to text.
|
64 | //!
|
65 | //! Command API:
|
66 | //!
|
67 | //! Using the Command API to set attributes.
|
68 | //!
|
69 | //! ```no_run
|
70 | //! use std::io::{self, Write};
|
71 | //!
|
72 | //! use crossterm::execute;
|
73 | //! use crossterm::style::{Attribute, Print, SetAttribute};
|
74 | //!
|
75 | //! fn main() -> io::Result<()> {
|
76 | //! execute!(
|
77 | //! io::stdout(),
|
78 | //! // Set to bold
|
79 | //! SetAttribute(Attribute::Bold),
|
80 | //! Print("Bold text here." .to_string()),
|
81 | //! // Reset all attributes
|
82 | //! SetAttribute(Attribute::Reset)
|
83 | //! )
|
84 | //! }
|
85 | //! ```
|
86 | //!
|
87 | //! Functions:
|
88 | //!
|
89 | //! Using [`Stylize`](crate::style::Stylize) functions on a `String` or `&'static str` to set
|
90 | //! attributes to it.
|
91 | //!
|
92 | //! ```no_run
|
93 | //! use crossterm::style::Stylize;
|
94 | //!
|
95 | //! println!("{}" , "Bold" .bold());
|
96 | //! println!("{}" , "Underlined" .underlined());
|
97 | //! println!("{}" , "Negative" .negative());
|
98 | //! ```
|
99 | //!
|
100 | //! Displayable:
|
101 | //!
|
102 | //! [`Attribute`](enum.Attribute.html) implements [Display](https://doc.rust-lang.org/beta/std/fmt/trait.Display.html) and therefore it can be formatted like:
|
103 | //!
|
104 | //! ```no_run
|
105 | //! use crossterm::style::Attribute;
|
106 | //!
|
107 | //! println!(
|
108 | //! "{} Underlined {} No Underline" ,
|
109 | //! Attribute::Underlined,
|
110 | //! Attribute::NoUnderline
|
111 | //! );
|
112 | //! ```
|
113 |
|
114 | use std::{
|
115 | env,
|
116 | fmt::{self, Display},
|
117 | };
|
118 |
|
119 | use crate::command::execute_fmt;
|
120 | use crate::{csi, impl_display, Command};
|
121 |
|
122 | pub use self::{
|
123 | attributes::Attributes,
|
124 | content_style::ContentStyle,
|
125 | styled_content::StyledContent,
|
126 | stylize::Stylize,
|
127 | types::{Attribute, Color, Colored, Colors},
|
128 | };
|
129 |
|
130 | mod attributes;
|
131 | mod content_style;
|
132 | mod styled_content;
|
133 | mod stylize;
|
134 | mod sys;
|
135 | mod types;
|
136 |
|
137 | /// Creates a `StyledContent`.
|
138 | ///
|
139 | /// This could be used to style any type that implements `Display` with colors and text attributes.
|
140 | ///
|
141 | /// See [`StyledContent`](struct.StyledContent.html) for more info.
|
142 | ///
|
143 | /// # Examples
|
144 | ///
|
145 | /// ```no_run
|
146 | /// use crossterm::style::{style, Stylize, Color};
|
147 | ///
|
148 | /// let styled_content = style("Blue colored text on yellow background" )
|
149 | /// .with(Color::Blue)
|
150 | /// .on(Color::Yellow);
|
151 | ///
|
152 | /// println!("{}" , styled_content);
|
153 | /// ```
|
154 | pub fn style<D: Display>(val: D) -> StyledContent<D> {
|
155 | ContentStyle::new().apply(val)
|
156 | }
|
157 |
|
158 | /// Returns available color count.
|
159 | ///
|
160 | /// # Notes
|
161 | ///
|
162 | /// This does not always provide a good result.
|
163 | pub fn available_color_count() -> u16 {
|
164 | #[cfg (windows)]
|
165 | {
|
166 | // Check if we're running in a pseudo TTY, which supports true color.
|
167 | // Fall back to env vars otherwise for other terminals on Windows.
|
168 | if crate::ansi_support::supports_ansi() {
|
169 | return u16::MAX;
|
170 | }
|
171 | }
|
172 |
|
173 | const DEFAULT: u16 = 8;
|
174 | env::var("COLORTERM" )
|
175 | .or_else(|_| env::var("TERM" ))
|
176 | .map_or(DEFAULT, |x: String| match x {
|
177 | _ if x.contains("24bit" ) || x.contains("truecolor" ) => u16::MAX,
|
178 | _ if x.contains("256" ) => 256,
|
179 | _ => DEFAULT,
|
180 | })
|
181 | }
|
182 |
|
183 | /// Forces colored output on or off globally, overriding NO_COLOR.
|
184 | ///
|
185 | /// # Notes
|
186 | ///
|
187 | /// crossterm supports NO_COLOR (<https://no-color.org/>) to disabled colored output.
|
188 | ///
|
189 | /// This API allows applications to override that behavior and force colorized output
|
190 | /// even if NO_COLOR is set.
|
191 | pub fn force_color_output(enabled: bool) {
|
192 | Colored::set_ansi_color_disabled(!enabled)
|
193 | }
|
194 |
|
195 | /// A command that sets the the foreground color.
|
196 | ///
|
197 | /// See [`Color`](enum.Color.html) for more info.
|
198 | ///
|
199 | /// [`SetColors`](struct.SetColors.html) can also be used to set both the foreground and background
|
200 | /// color in one command.
|
201 | ///
|
202 | /// # Notes
|
203 | ///
|
204 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
205 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
206 | pub struct SetForegroundColor(pub Color);
|
207 |
|
208 | impl Command for SetForegroundColor {
|
209 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
210 | write!(f, csi!("{}m" ), Colored::ForegroundColor(self.0))
|
211 | }
|
212 |
|
213 | #[cfg (windows)]
|
214 | fn execute_winapi(&self) -> std::io::Result<()> {
|
215 | sys::windows::set_foreground_color(self.0)
|
216 | }
|
217 | }
|
218 |
|
219 | /// A command that sets the the background color.
|
220 | ///
|
221 | /// See [`Color`](enum.Color.html) for more info.
|
222 | ///
|
223 | /// [`SetColors`](struct.SetColors.html) can also be used to set both the foreground and background
|
224 | /// color with one command.
|
225 | ///
|
226 | /// # Notes
|
227 | ///
|
228 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
229 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
230 | pub struct SetBackgroundColor(pub Color);
|
231 |
|
232 | impl Command for SetBackgroundColor {
|
233 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
234 | write!(f, csi!("{}m" ), Colored::BackgroundColor(self.0))
|
235 | }
|
236 |
|
237 | #[cfg (windows)]
|
238 | fn execute_winapi(&self) -> std::io::Result<()> {
|
239 | sys::windows::set_background_color(self.0)
|
240 | }
|
241 | }
|
242 |
|
243 | /// A command that sets the the underline color.
|
244 | ///
|
245 | /// See [`Color`](enum.Color.html) for more info.
|
246 | ///
|
247 | /// [`SetColors`](struct.SetColors.html) can also be used to set both the foreground and background
|
248 | /// color with one command.
|
249 | ///
|
250 | /// # Notes
|
251 | ///
|
252 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
253 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
254 | pub struct SetUnderlineColor(pub Color);
|
255 |
|
256 | impl Command for SetUnderlineColor {
|
257 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
258 | write!(f, csi!("{}m" ), Colored::UnderlineColor(self.0))
|
259 | }
|
260 |
|
261 | #[cfg (windows)]
|
262 | fn execute_winapi(&self) -> std::io::Result<()> {
|
263 | Err(std::io::Error::new(
|
264 | std::io::ErrorKind::Other,
|
265 | "SetUnderlineColor not supported by winapi." ,
|
266 | ))
|
267 | }
|
268 | }
|
269 |
|
270 | /// A command that optionally sets the foreground and/or background color.
|
271 | ///
|
272 | /// For example:
|
273 | /// ```no_run
|
274 | /// use std::io::{stdout, Write};
|
275 | ///
|
276 | /// use crossterm::execute;
|
277 | /// use crossterm::style::{Color::{Green, Black}, Colors, Print, SetColors};
|
278 | ///
|
279 | /// execute!(
|
280 | /// stdout(),
|
281 | /// SetColors(Colors::new(Green, Black)),
|
282 | /// Print("Hello, world!" .to_string()),
|
283 | /// ).unwrap();
|
284 | /// ```
|
285 | ///
|
286 | /// See [`Colors`](struct.Colors.html) for more info.
|
287 | ///
|
288 | /// # Notes
|
289 | ///
|
290 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
291 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
292 | pub struct SetColors(pub Colors);
|
293 |
|
294 | impl Command for SetColors {
|
295 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
296 | // Writing both foreground and background colors in one command resulted in about 20% more
|
297 | // FPS (20 to 24 fps) on a fullscreen (171x51) app that writes every cell with a different
|
298 | // foreground and background color, compared to separately using the SetForegroundColor and
|
299 | // SetBackgroundColor commands (iTerm2, M2 Macbook Pro). `Esc[38;5;<fg>mEsc[48;5;<bg>m` (16
|
300 | // chars) vs `Esc[38;5;<fg>;48;5;<bg>m` (14 chars)
|
301 | match (self.0.foreground, self.0.background) {
|
302 | (Some(fg), Some(bg)) => {
|
303 | write!(
|
304 | f,
|
305 | csi!("{};{}m" ),
|
306 | Colored::ForegroundColor(fg),
|
307 | Colored::BackgroundColor(bg)
|
308 | )
|
309 | }
|
310 | (Some(fg), None) => write!(f, csi!("{}m" ), Colored::ForegroundColor(fg)),
|
311 | (None, Some(bg)) => write!(f, csi!("{}m" ), Colored::BackgroundColor(bg)),
|
312 | (None, None) => Ok(()),
|
313 | }
|
314 | }
|
315 |
|
316 | #[cfg (windows)]
|
317 | fn execute_winapi(&self) -> std::io::Result<()> {
|
318 | if let Some(color) = self.0.foreground {
|
319 | sys::windows::set_foreground_color(color)?;
|
320 | }
|
321 | if let Some(color) = self.0.background {
|
322 | sys::windows::set_background_color(color)?;
|
323 | }
|
324 | Ok(())
|
325 | }
|
326 | }
|
327 |
|
328 | /// A command that sets an attribute.
|
329 | ///
|
330 | /// See [`Attribute`](enum.Attribute.html) for more info.
|
331 | ///
|
332 | /// # Notes
|
333 | ///
|
334 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
335 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
336 | pub struct SetAttribute(pub Attribute);
|
337 |
|
338 | impl Command for SetAttribute {
|
339 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
340 | write!(f, csi!("{}m" ), self.0.sgr())
|
341 | }
|
342 |
|
343 | #[cfg (windows)]
|
344 | fn execute_winapi(&self) -> std::io::Result<()> {
|
345 | // attributes are not supported by WinAPI.
|
346 | Ok(())
|
347 | }
|
348 | }
|
349 |
|
350 | /// A command that sets several attributes.
|
351 | ///
|
352 | /// See [`Attributes`](struct.Attributes.html) for more info.
|
353 | ///
|
354 | /// # Notes
|
355 | ///
|
356 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
357 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
358 | pub struct SetAttributes(pub Attributes);
|
359 |
|
360 | impl Command for SetAttributes {
|
361 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
362 | for attr: Attribute in Attribute::iterator() {
|
363 | if self.0.has(attribute:attr) {
|
364 | SetAttribute(attr).write_ansi(f)?;
|
365 | }
|
366 | }
|
367 | Ok(())
|
368 | }
|
369 |
|
370 | #[cfg (windows)]
|
371 | fn execute_winapi(&self) -> std::io::Result<()> {
|
372 | // attributes are not supported by WinAPI.
|
373 | Ok(())
|
374 | }
|
375 | }
|
376 |
|
377 | /// A command that sets a style (colors and attributes).
|
378 | ///
|
379 | /// # Notes
|
380 | ///
|
381 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
382 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
383 | pub struct SetStyle(pub ContentStyle);
|
384 |
|
385 | impl Command for SetStyle {
|
386 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
387 | if let Some(bg) = self.0.background_color {
|
388 | execute_fmt(f, SetBackgroundColor(bg)).map_err(|_| fmt::Error)?;
|
389 | }
|
390 | if let Some(fg) = self.0.foreground_color {
|
391 | execute_fmt(f, SetForegroundColor(fg)).map_err(|_| fmt::Error)?;
|
392 | }
|
393 | if let Some(ul) = self.0.underline_color {
|
394 | execute_fmt(f, SetUnderlineColor(ul)).map_err(|_| fmt::Error)?;
|
395 | }
|
396 | if !self.0.attributes.is_empty() {
|
397 | execute_fmt(f, SetAttributes(self.0.attributes)).map_err(|_| fmt::Error)?;
|
398 | }
|
399 |
|
400 | Ok(())
|
401 | }
|
402 |
|
403 | #[cfg (windows)]
|
404 | fn execute_winapi(&self) -> std::io::Result<()> {
|
405 | panic!("tried to execute SetStyle command using WinAPI, use ANSI instead" );
|
406 | }
|
407 |
|
408 | #[cfg (windows)]
|
409 | fn is_ansi_code_supported(&self) -> bool {
|
410 | true
|
411 | }
|
412 | }
|
413 |
|
414 | /// A command that prints styled content.
|
415 | ///
|
416 | /// See [`StyledContent`](struct.StyledContent.html) for more info.
|
417 | ///
|
418 | /// # Notes
|
419 | ///
|
420 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
421 | #[derive (Debug, Copy, Clone)]
|
422 | pub struct PrintStyledContent<D: Display>(pub StyledContent<D>);
|
423 |
|
424 | impl<D: Display> Command for PrintStyledContent<D> {
|
425 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
426 | let style = self.0.style();
|
427 |
|
428 | let mut reset_background = false;
|
429 | let mut reset_foreground = false;
|
430 | let mut reset = false;
|
431 |
|
432 | if let Some(bg) = style.background_color {
|
433 | execute_fmt(f, SetBackgroundColor(bg)).map_err(|_| fmt::Error)?;
|
434 | reset_background = true;
|
435 | }
|
436 | if let Some(fg) = style.foreground_color {
|
437 | execute_fmt(f, SetForegroundColor(fg)).map_err(|_| fmt::Error)?;
|
438 | reset_foreground = true;
|
439 | }
|
440 | if let Some(ul) = style.underline_color {
|
441 | execute_fmt(f, SetUnderlineColor(ul)).map_err(|_| fmt::Error)?;
|
442 | reset_foreground = true;
|
443 | }
|
444 |
|
445 | if !style.attributes.is_empty() {
|
446 | execute_fmt(f, SetAttributes(style.attributes)).map_err(|_| fmt::Error)?;
|
447 | reset = true;
|
448 | }
|
449 |
|
450 | write!(f, " {}" , self.0.content())?;
|
451 |
|
452 | if reset {
|
453 | // NOTE: This will reset colors even though self has no colors, hence produce unexpected
|
454 | // resets.
|
455 | // TODO: reset the set attributes only.
|
456 | execute_fmt(f, ResetColor).map_err(|_| fmt::Error)?;
|
457 | } else {
|
458 | // NOTE: Since the above bug, we do not need to reset colors when we reset attributes.
|
459 | if reset_background {
|
460 | execute_fmt(f, SetBackgroundColor(Color::Reset)).map_err(|_| fmt::Error)?;
|
461 | }
|
462 | if reset_foreground {
|
463 | execute_fmt(f, SetForegroundColor(Color::Reset)).map_err(|_| fmt::Error)?;
|
464 | }
|
465 | }
|
466 |
|
467 | Ok(())
|
468 | }
|
469 |
|
470 | #[cfg (windows)]
|
471 | fn execute_winapi(&self) -> std::io::Result<()> {
|
472 | Ok(())
|
473 | }
|
474 | }
|
475 |
|
476 | /// A command that resets the colors back to default.
|
477 | ///
|
478 | /// # Notes
|
479 | ///
|
480 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
481 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
482 | pub struct ResetColor;
|
483 |
|
484 | impl Command for ResetColor {
|
485 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
486 | f.write_str(csi!("0m" ))
|
487 | }
|
488 |
|
489 | #[cfg (windows)]
|
490 | fn execute_winapi(&self) -> std::io::Result<()> {
|
491 | sys::windows::reset()
|
492 | }
|
493 | }
|
494 |
|
495 | /// A command that prints the given displayable type.
|
496 | ///
|
497 | /// Commands must be executed/queued for execution otherwise they do nothing.
|
498 | #[derive (Debug, Clone, Copy, PartialEq, Eq)]
|
499 | pub struct Print<T: Display>(pub T);
|
500 |
|
501 | impl<T: Display> Command for Print<T> {
|
502 | fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
503 | write!(f, " {}" , self.0)
|
504 | }
|
505 |
|
506 | #[cfg (windows)]
|
507 | fn execute_winapi(&self) -> std::io::Result<()> {
|
508 | panic!("tried to execute Print command using WinAPI, use ANSI instead" );
|
509 | }
|
510 |
|
511 | #[cfg (windows)]
|
512 | fn is_ansi_code_supported(&self) -> bool {
|
513 | true
|
514 | }
|
515 | }
|
516 |
|
517 | impl<T: Display> Display for Print<T> {
|
518 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
519 | self.0.fmt(f)
|
520 | }
|
521 | }
|
522 |
|
523 | impl_display!(for SetForegroundColor);
|
524 | impl_display!(for SetBackgroundColor);
|
525 | impl_display!(for SetColors);
|
526 | impl_display!(for SetAttribute);
|
527 | impl_display!(for PrintStyledContent<String>);
|
528 | impl_display!(for PrintStyledContent<&'static str>);
|
529 | impl_display!(for ResetColor);
|
530 |
|
531 | /// Utility function for ANSI parsing in Color and Colored.
|
532 | /// Gets the next element of `iter` and tries to parse it as a `u8`.
|
533 | fn parse_next_u8<'a>(iter: &mut impl Iterator<Item = &'a str>) -> Option<u8> {
|
534 | iter.next().and_then(|s: &'a str| s.parse().ok())
|
535 | }
|
536 |
|
537 | #[cfg (test)]
|
538 | mod tests {
|
539 | use super::*;
|
540 |
|
541 | // On Windows many env var tests will fail so we need to conditionally check for ANSI support.
|
542 | // This allows other terminals on Windows to still assert env var support.
|
543 | macro_rules! skip_windows_ansi_supported {
|
544 | () => {
|
545 | #[cfg(windows)]
|
546 | {
|
547 | if crate::ansi_support::supports_ansi() {
|
548 | return;
|
549 | }
|
550 | }
|
551 | };
|
552 | }
|
553 |
|
554 | #[cfg_attr (windows, test)]
|
555 | #[cfg (windows)]
|
556 | fn windows_always_truecolor() {
|
557 | // This should always be true on supported Windows 10+,
|
558 | // but downlevel Windows clients and other terminals may fail `cargo test` otherwise.
|
559 | if crate::ansi_support::supports_ansi() {
|
560 | assert_eq!(u16::MAX, available_color_count());
|
561 | };
|
562 | }
|
563 |
|
564 | #[test ]
|
565 | fn colorterm_overrides_term() {
|
566 | skip_windows_ansi_supported!();
|
567 | temp_env::with_vars(
|
568 | [
|
569 | ("COLORTERM" , Some("truecolor" )),
|
570 | ("TERM" , Some("xterm-256color" )),
|
571 | ],
|
572 | || {
|
573 | assert_eq!(u16::MAX, available_color_count());
|
574 | },
|
575 | );
|
576 | }
|
577 |
|
578 | #[test ]
|
579 | fn term_24bits() {
|
580 | skip_windows_ansi_supported!();
|
581 | temp_env::with_vars(
|
582 | [("COLORTERM" , None), ("TERM" , Some("xterm-24bits" ))],
|
583 | || {
|
584 | assert_eq!(u16::MAX, available_color_count());
|
585 | },
|
586 | );
|
587 | }
|
588 |
|
589 | #[test ]
|
590 | fn term_256color() {
|
591 | skip_windows_ansi_supported!();
|
592 | temp_env::with_vars(
|
593 | [("COLORTERM" , None), ("TERM" , Some("xterm-256color" ))],
|
594 | || {
|
595 | assert_eq!(256u16, available_color_count());
|
596 | },
|
597 | );
|
598 | }
|
599 |
|
600 | #[test ]
|
601 | fn default_color_count() {
|
602 | skip_windows_ansi_supported!();
|
603 | temp_env::with_vars([("COLORTERM" , None::<&str>), ("TERM" , None)], || {
|
604 | assert_eq!(8, available_color_count());
|
605 | });
|
606 | }
|
607 |
|
608 | #[test ]
|
609 | fn unsupported_term_colorterm_values() {
|
610 | skip_windows_ansi_supported!();
|
611 | temp_env::with_vars(
|
612 | [
|
613 | ("COLORTERM" , Some("gibberish" )),
|
614 | ("TERM" , Some("gibberish" )),
|
615 | ],
|
616 | || {
|
617 | assert_eq!(8u16, available_color_count());
|
618 | },
|
619 | );
|
620 | }
|
621 | }
|
622 | |