]>
git.proxmox.com Git - rustc.git/blob - vendor/nu-ansi-term-0.46.0/src/ansi.rs
1 #![allow(missing_docs)]
2 use crate::style
::{Color, Style}
;
3 use crate::write
::AnyWrite
;
7 /// Write any bytes that go *before* a piece of text to the given writer.
8 fn write_prefix
<W
: AnyWrite
+ ?Sized
>(&self, f
: &mut W
) -> Result
<(), W
::Error
> {
9 // If there are actually no styles here, then don’t write *any* codes
10 // as the prefix. An empty ANSI code may not affect the terminal
11 // output at all, but a user may just want a code-free string.
16 // Write the codes’ prefix, then write numbers, separated by
17 // semicolons, for each text style we want to apply.
19 let mut written_anything
= false;
22 let mut write_char
= |c
| {
26 written_anything
= true;
40 if self.is_underline
{
52 if self.is_strikethrough
{
57 // The foreground and background colors, if specified, need to be
58 // handled specially because the number codes are more complicated.
59 // (see `write_background_code` and `write_foreground_code`)
60 if let Some(bg
) = self.background
{
64 written_anything
= true;
65 bg
.write_background_code(f
)?
;
68 if let Some(fg
) = self.foreground
{
72 fg
.write_foreground_code(f
)?
;
75 // All the codes end with an `m`, because reasons.
81 /// Write any bytes that go *after* a piece of text to the given writer.
82 fn write_suffix
<W
: AnyWrite
+ ?Sized
>(&self, f
: &mut W
) -> Result
<(), W
::Error
> {
86 write
!(f
, "{}", RESET
)
91 /// The code to send to reset all styles and return to `Style::default()`.
92 pub static RESET
: &str = "\x1B[0m";
95 fn write_foreground_code
<W
: AnyWrite
+ ?Sized
>(&self, f
: &mut W
) -> Result
<(), W
::Error
> {
97 Color
::Black
=> write
!(f
, "30"),
98 Color
::Red
=> write
!(f
, "31"),
99 Color
::Green
=> write
!(f
, "32"),
100 Color
::Yellow
=> write
!(f
, "33"),
101 Color
::Blue
=> write
!(f
, "34"),
102 Color
::Purple
=> write
!(f
, "35"),
103 Color
::Magenta
=> write
!(f
, "35"),
104 Color
::Cyan
=> write
!(f
, "36"),
105 Color
::White
=> write
!(f
, "37"),
106 Color
::Fixed(num
) => write
!(f
, "38;5;{}", num
),
107 Color
::Rgb(r
, g
, b
) => write
!(f
, "38;2;{};{};{}", r
, g
, b
),
108 Color
::Default
=> write
!(f
, "39"),
109 Color
::DarkGray
=> write
!(f
, "90"),
110 Color
::LightRed
=> write
!(f
, "91"),
111 Color
::LightGreen
=> write
!(f
, "92"),
112 Color
::LightYellow
=> write
!(f
, "93"),
113 Color
::LightBlue
=> write
!(f
, "94"),
114 Color
::LightPurple
=> write
!(f
, "95"),
115 Color
::LightMagenta
=> write
!(f
, "95"),
116 Color
::LightCyan
=> write
!(f
, "96"),
117 Color
::LightGray
=> write
!(f
, "97"),
121 fn write_background_code
<W
: AnyWrite
+ ?Sized
>(&self, f
: &mut W
) -> Result
<(), W
::Error
> {
123 Color
::Black
=> write
!(f
, "40"),
124 Color
::Red
=> write
!(f
, "41"),
125 Color
::Green
=> write
!(f
, "42"),
126 Color
::Yellow
=> write
!(f
, "43"),
127 Color
::Blue
=> write
!(f
, "44"),
128 Color
::Purple
=> write
!(f
, "45"),
129 Color
::Magenta
=> write
!(f
, "45"),
130 Color
::Cyan
=> write
!(f
, "46"),
131 Color
::White
=> write
!(f
, "47"),
132 Color
::Fixed(num
) => write
!(f
, "48;5;{}", num
),
133 Color
::Rgb(r
, g
, b
) => write
!(f
, "48;2;{};{};{}", r
, g
, b
),
134 Color
::Default
=> write
!(f
, "49"),
135 Color
::DarkGray
=> write
!(f
, "100"),
136 Color
::LightRed
=> write
!(f
, "101"),
137 Color
::LightGreen
=> write
!(f
, "102"),
138 Color
::LightYellow
=> write
!(f
, "103"),
139 Color
::LightBlue
=> write
!(f
, "104"),
140 Color
::LightPurple
=> write
!(f
, "105"),
141 Color
::LightMagenta
=> write
!(f
, "105"),
142 Color
::LightCyan
=> write
!(f
, "106"),
143 Color
::LightGray
=> write
!(f
, "107"),
148 /// Like `AnsiString`, but only displays the style prefix.
150 /// This type implements the `Display` trait, meaning it can be written to a
151 /// `std::fmt` formatting without doing any extra allocation, and written to a
152 /// string with the `.to_string()` method. For examples, see
153 /// [`Style::prefix`](struct.Style.html#method.prefix).
154 #[derive(Clone, Copy, Debug)]
155 pub struct Prefix(Style
);
157 /// Like `AnsiString`, but only displays the difference between two
160 /// This type implements the `Display` trait, meaning it can be written to a
161 /// `std::fmt` formatting without doing any extra allocation, and written to a
162 /// string with the `.to_string()` method. For examples, see
163 /// [`Style::infix`](struct.Style.html#method.infix).
164 #[derive(Clone, Copy, Debug)]
165 pub struct Infix(Style
, Style
);
167 /// Like `AnsiString`, but only displays the style suffix.
169 /// This type implements the `Display` trait, meaning it can be written to a
170 /// `std::fmt` formatting without doing any extra allocation, and written to a
171 /// string with the `.to_string()` method. For examples, see
172 /// [`Style::suffix`](struct.Style.html#method.suffix).
173 #[derive(Clone, Copy, Debug)]
174 pub struct Suffix(Style
);
177 /// The prefix bytes for this style. These are the bytes that tell the
178 /// terminal to use a different color or font style.
183 /// use nu_ansi_term::{Style, Color::Blue};
185 /// let style = Style::default().bold();
186 /// assert_eq!("\x1b[1m",
187 /// style.prefix().to_string());
189 /// let style = Blue.bold();
190 /// assert_eq!("\x1b[1;34m",
191 /// style.prefix().to_string());
193 /// let style = Style::default();
195 /// style.prefix().to_string());
197 pub fn prefix(self) -> Prefix
{
201 /// The infix bytes between this style and `next` style. These are the bytes
202 /// that tell the terminal to change the style to `next`. These may include
203 /// a reset followed by the next color and style, depending on the two styles.
208 /// use nu_ansi_term::{Style, Color::Green};
210 /// let style = Style::default().bold();
211 /// assert_eq!("\x1b[32m",
212 /// style.infix(Green.bold()).to_string());
214 /// let style = Green.normal();
215 /// assert_eq!("\x1b[1m",
216 /// style.infix(Green.bold()).to_string());
218 /// let style = Style::default();
220 /// style.infix(style).to_string());
222 pub fn infix(self, next
: Style
) -> Infix
{
226 /// The suffix for this style. These are the bytes that tell the terminal
227 /// to reset back to its normal color and font style.
232 /// use nu_ansi_term::{Style, Color::Green};
234 /// let style = Style::default().bold();
235 /// assert_eq!("\x1b[0m",
236 /// style.suffix().to_string());
238 /// let style = Green.normal().bold();
239 /// assert_eq!("\x1b[0m",
240 /// style.suffix().to_string());
242 /// let style = Style::default();
244 /// style.suffix().to_string());
246 pub fn suffix(self) -> Suffix
{
252 /// The prefix bytes for this color as a `Style`. These are the bytes
253 /// that tell the terminal to use a different color or font style.
255 /// See also [`Style::prefix`](struct.Style.html#method.prefix).
260 /// use nu_ansi_term::Color::Green;
262 /// assert_eq!("\x1b[0m",
263 /// Green.suffix().to_string());
265 pub fn prefix(self) -> Prefix
{
266 Prefix(self.normal())
269 /// The infix bytes between this color and `next` color. These are the bytes
270 /// that tell the terminal to use the `next` color, or to do nothing if
271 /// the two colors are equal.
273 /// See also [`Style::infix`](struct.Style.html#method.infix).
278 /// use nu_ansi_term::Color::{Red, Yellow};
280 /// assert_eq!("\x1b[33m",
281 /// Red.infix(Yellow).to_string());
283 pub fn infix(self, next
: Color
) -> Infix
{
284 Infix(self.normal(), next
.normal())
287 /// The suffix for this color as a `Style`. These are the bytes that
288 /// tell the terminal to reset back to its normal color and font style.
290 /// See also [`Style::suffix`](struct.Style.html#method.suffix).
295 /// use nu_ansi_term::Color::Purple;
297 /// assert_eq!("\x1b[0m",
298 /// Purple.suffix().to_string());
300 pub fn suffix(self) -> Suffix
{
301 Suffix(self.normal())
305 impl fmt
::Display
for Prefix
{
306 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
307 let f
: &mut dyn fmt
::Write
= f
;
308 self.0.write_prefix(f
)
312 impl fmt
::Display
for Infix
{
313 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
314 use crate::difference
::Difference
;
316 match Difference
::between(&self.0, &self.1) {
317 Difference
::ExtraStyles(style
) => {
318 let f
: &mut dyn fmt
::Write
= f
;
319 style
.write_prefix(f
)
321 Difference
::Reset
=> {
322 let f
: &mut dyn fmt
::Write
= f
;
323 write
!(f
, "{}{}", RESET
, self.1.prefix())
325 Difference
::Empty
=> {
326 Ok(()) // nothing to write
332 impl fmt
::Display
for Suffix
{
333 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
334 let f
: &mut dyn fmt
::Write
= f
;
335 self.0.write_suffix(f
)
341 use crate::style
::Color
::*;
342 use crate::style
::Style
;
345 ($name
: ident
: $style
: expr
; $input
: expr
=> $result
: expr
) => {
348 assert_eq
!($style
.paint($input
).to_string(), $result
.to_string());
350 let mut v
= Vec
::new();
351 $style
.paint($input
.as_bytes()).write_to(&mut v
).unwrap();
352 assert_eq
!(v
.as_slice(), $result
.as_bytes());
357 test
!(plain
: Style
::default(); "text/plain" => "text/plain");
358 test
!(red
: Red
; "hi" => "\x1B[31mhi\x1B[0m");
359 test
!(black
: Black
.normal(); "hi" => "\x1B[30mhi\x1B[0m");
360 test
!(yellow_bold
: Yellow
.bold(); "hi" => "\x1B[1;33mhi\x1B[0m");
361 test
!(yellow_bold_2
: Yellow
.normal().bold(); "hi" => "\x1B[1;33mhi\x1B[0m");
362 test
!(blue_underline
: Blue
.underline(); "hi" => "\x1B[4;34mhi\x1B[0m");
363 test
!(green_bold_ul
: Green
.bold().underline(); "hi" => "\x1B[1;4;32mhi\x1B[0m");
364 test
!(green_bold_ul_2
: Green
.underline().bold(); "hi" => "\x1B[1;4;32mhi\x1B[0m");
365 test
!(purple_on_white
: Purple
.on(White
); "hi" => "\x1B[47;35mhi\x1B[0m");
366 test
!(purple_on_white_2
: Purple
.normal().on(White
); "hi" => "\x1B[47;35mhi\x1B[0m");
367 test
!(yellow_on_blue
: Style
::new().on(Blue
).fg(Yellow
); "hi" => "\x1B[44;33mhi\x1B[0m");
368 test
!(magenta_on_white
: Magenta
.on(White
); "hi" => "\x1B[47;35mhi\x1B[0m");
369 test
!(magenta_on_white_2
: Magenta
.normal().on(White
); "hi" => "\x1B[47;35mhi\x1B[0m");
370 test
!(yellow_on_blue_2
: Cyan
.on(Blue
).fg(Yellow
); "hi" => "\x1B[44;33mhi\x1B[0m");
371 test
!(cyan_bold_on_white
: Cyan
.bold().on(White
); "hi" => "\x1B[1;47;36mhi\x1B[0m");
372 test
!(cyan_ul_on_white
: Cyan
.underline().on(White
); "hi" => "\x1B[4;47;36mhi\x1B[0m");
373 test
!(cyan_bold_ul_on_white
: Cyan
.bold().underline().on(White
); "hi" => "\x1B[1;4;47;36mhi\x1B[0m");
374 test
!(cyan_ul_bold_on_white
: Cyan
.underline().bold().on(White
); "hi" => "\x1B[1;4;47;36mhi\x1B[0m");
375 test
!(fixed
: Fixed(100); "hi" => "\x1B[38;5;100mhi\x1B[0m");
376 test
!(fixed_on_purple
: Fixed(100).on(Purple
); "hi" => "\x1B[45;38;5;100mhi\x1B[0m");
377 test
!(fixed_on_fixed
: Fixed(100).on(Fixed(200)); "hi" => "\x1B[48;5;200;38;5;100mhi\x1B[0m");
378 test
!(rgb
: Rgb(70,130,180); "hi" => "\x1B[38;2;70;130;180mhi\x1B[0m");
379 test
!(rgb_on_blue
: Rgb(70,130,180).on(Blue
); "hi" => "\x1B[44;38;2;70;130;180mhi\x1B[0m");
380 test
!(blue_on_rgb
: Blue
.on(Rgb(70,130,180)); "hi" => "\x1B[48;2;70;130;180;34mhi\x1B[0m");
381 test
!(rgb_on_rgb
: Rgb(70,130,180).on(Rgb(5,10,15)); "hi" => "\x1B[48;2;5;10;15;38;2;70;130;180mhi\x1B[0m");
382 test
!(bold
: Style
::new().bold(); "hi" => "\x1B[1mhi\x1B[0m");
383 test
!(underline
: Style
::new().underline(); "hi" => "\x1B[4mhi\x1B[0m");
384 test
!(bunderline
: Style
::new().bold().underline(); "hi" => "\x1B[1;4mhi\x1B[0m");
385 test
!(dimmed
: Style
::new().dimmed(); "hi" => "\x1B[2mhi\x1B[0m");
386 test
!(italic
: Style
::new().italic(); "hi" => "\x1B[3mhi\x1B[0m");
387 test
!(blink
: Style
::new().blink(); "hi" => "\x1B[5mhi\x1B[0m");
388 test
!(reverse
: Style
::new().reverse(); "hi" => "\x1B[7mhi\x1B[0m");
389 test
!(hidden
: Style
::new().hidden(); "hi" => "\x1B[8mhi\x1B[0m");
390 test
!(stricken
: Style
::new().strikethrough(); "hi" => "\x1B[9mhi\x1B[0m");
391 test
!(lr_on_lr
: LightRed
.on(LightRed
); "hi" => "\x1B[101;91mhi\x1B[0m");
396 Style
::new().dimmed().infix(Style
::new()).to_string(),
400 White
.dimmed().infix(White
.normal()).to_string(),
403 assert_eq
!(White
.normal().infix(White
.bold()).to_string(), "\x1B[1m");
404 assert_eq
!(White
.normal().infix(Blue
.normal()).to_string(), "\x1B[34m");
405 assert_eq
!(Blue
.bold().infix(Blue
.bold()).to_string(), "");