diff --git a/Cargo.lock b/Cargo.lock index 8fc0febe2d34..7d975b084838 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5041,11 +5041,11 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ - "wincolor", + "winapi-util", ] [[package]] @@ -5865,16 +5865,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "wincolor" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" -dependencies = [ - "winapi", - "winapi-util", -] - [[package]] name = "wineventlog" version = "0.1.0" diff --git a/third_party/rust/termcolor/.cargo-checksum.json b/third_party/rust/termcolor/.cargo-checksum.json index ab4b98349dbe..b4df1ed20711 100644 --- a/third_party/rust/termcolor/.cargo-checksum.json +++ b/third_party/rust/termcolor/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"6aa6756345334b141f6ecc768420d0f4b38617b521dc470640a819ec50c733f2","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"91f15c930f170ad8199d603315228fdb16ee865ea8f04f5156af5d45fd1eb430","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","src/lib.rs":"d2096632374fe044540abe35a36d23c37a19eb1153bc589b96729081504f23b9"},"package":"96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"} \ No newline at end of file +{"files":{"COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"8d7cf2f58e13533f446cfe1d0c045461974d05d675c1dbda029d912a491d7271","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"5818a900b5f23ed13e824479c4739e3afe7929a5a08e0dcfdf2cc61ba019d986","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/lib.rs":"5aa9530c1de59aa0f19b035270f87e10397ef37eba317366b9504058364f1d78"},"package":"2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"} \ No newline at end of file diff --git a/third_party/rust/termcolor/Cargo.toml b/third_party/rust/termcolor/Cargo.toml index a03e72d1e6e3..344e18bbb2f1 100644 --- a/third_party/rust/termcolor/Cargo.toml +++ b/third_party/rust/termcolor/Cargo.toml @@ -11,8 +11,9 @@ # will likely look very different (and much more reasonable) [package] +edition = "2018" name = "termcolor" -version = "1.0.5" +version = "1.1.2" authors = ["Andrew Gallant "] exclude = ["/.travis.yml", "/appveyor.yml", "/ci/**"] description = "A simple cross platform library for writing colored text to a terminal.\n" @@ -26,5 +27,7 @@ repository = "https://github.com/BurntSushi/termcolor" [lib] name = "termcolor" bench = false -[target."cfg(windows)".dependencies.wincolor] -version = "1" + +[dev-dependencies] +[target."cfg(windows)".dependencies.winapi-util] +version = "0.1.3" diff --git a/third_party/rust/termcolor/README.md b/third_party/rust/termcolor/README.md index faf3edb2daf5..1c91d07bff48 100644 --- a/third_party/rust/termcolor/README.md +++ b/third_party/rust/termcolor/README.md @@ -6,8 +6,7 @@ by interacting with the Windows console. Several convenient abstractions are provided for use in single-threaded or multi-threaded command line applications. -[![Linux build status](https://api.travis-ci.org/BurntSushi/termcolor.png)](https://travis-ci.org/BurntSushi/termcolor) -[![Windows build status](https://ci.appveyor.com/api/projects/status/github/BurntSushi/termcolor?svg=true)](https://ci.appveyor.com/project/BurntSushi/termcolor) +[![Build status](https://github.com/BurntSushi/termcolor/workflows/ci/badge.svg)](https://github.com/BurntSushi/termcolor/actions) [![](https://img.shields.io/crates/v/termcolor.svg)](https://crates.io/crates/termcolor) Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org). @@ -22,13 +21,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -termcolor = "1" -``` - -and this to your crate root: - -```rust -extern crate termcolor; +termcolor = "1.1" ``` ### Organization @@ -58,12 +51,14 @@ except it is augmented with methods for coloring by the `WriteColor` trait. For example, to write some green text: ```rust -use std::io::Write; +use std::io::{self, Write}; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; -let mut stdout = StandardStream::stdout(ColorChoice::Always); -stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; -writeln!(&mut stdout, "green text!")?; +fn write_green() -> io::Result<()> { + let mut stdout = StandardStream::stdout(ColorChoice::Always); + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; + writeln!(&mut stdout, "green text!") +} ``` ### Example: using `BufferWriter` @@ -75,12 +70,46 @@ implements `io::Write` and `termcolor::WriteColor`. This example shows how to print some green text to stderr. ```rust -use std::io::Write; +use std::io::{self, Write}; use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec, WriteColor}; -let mut bufwtr = BufferWriter::stderr(ColorChoice::Always); -let mut buffer = bufwtr.buffer(); -buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; -writeln!(&mut buffer, "green text!")?; -bufwtr.print(&buffer)?; +fn write_green() -> io::Result<()> { + let mut bufwtr = BufferWriter::stderr(ColorChoice::Always); + let mut buffer = bufwtr.buffer(); + buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; + writeln!(&mut buffer, "green text!")?; + bufwtr.print(&buffer) +} ``` + +### Automatic color selection + +When building a writer with termcolor, the caller must provide a +[`ColorChoice`](https://docs.rs/termcolor/1.0.5/termcolor/enum.ColorChoice.html) +selection. When the color choice is `Auto`, termcolor will attempt to determine +whether colors should be enabled by inspecting the environment. Currently, +termcolor will inspect the `TERM` and `NO_COLOR` environment variables: + +* If `NO_COLOR` is set to any value, then colors will be suppressed. +* If `TERM` is set to `dumb`, then colors will be suppressed. +* In non-Windows environments, if `TERM` is not set, then colors will be + suppressed. + +This decision procedure may change over time. + +Currently, `termcolor` does not attempt to detect whether a tty is present or +not. To achieve that, please use the [`atty`](https://crates.io/crates/atty) +crate. + +### Minimum Rust version policy + +This crate's minimum supported `rustc` version is `1.34.0`. + +The current policy is that the minimum Rust version required to use this crate +can be increased in minor version updates. For example, if `crate 1.0` requires +Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust +1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum +version of Rust. + +In general, this crate will be conservative with respect to the minimum +supported version of Rust. diff --git a/third_party/rust/termcolor/rustfmt.toml b/third_party/rust/termcolor/rustfmt.toml new file mode 100644 index 000000000000..aa37a218b97e --- /dev/null +++ b/third_party/rust/termcolor/rustfmt.toml @@ -0,0 +1,2 @@ +max_width = 79 +use_small_heuristics = "max" diff --git a/third_party/rust/termcolor/src/lib.rs b/third_party/rust/termcolor/src/lib.rs index f220b592f712..735ce97d20af 100644 --- a/third_party/rust/termcolor/src/lib.rs +++ b/third_party/rust/termcolor/src/lib.rs @@ -47,6 +47,14 @@ writeln!(&mut stdout, "green text!")?; # Ok(()) } ``` +Note that any text written to the terminal now will be colored +green when using ANSI escape sequences, even if it is written via +stderr, and even if stderr had previously been set to `Color::Red`. +Users will need to manage any color changes themselves by calling +[`WriteColor::set_color`](trait.WriteColor.html#tymethod.set_color), and this +may include calling [`WriteColor::reset`](trait.WriteColor.html#tymethod.reset) +before the program exits to a shell. + # Example: using `BufferWriter` A `BufferWriter` can create buffers and write buffers to stdout or stderr. It @@ -67,21 +75,66 @@ writeln!(&mut buffer, "green text!")?; bufwtr.print(&buffer)?; # Ok(()) } ``` + +# Detecting presence of a terminal + +In many scenarios when using color, one often wants to enable colors +automatically when writing to a terminal and disable colors automatically when +writing to anything else. The typical way to achieve this in Unix environments +is via libc's +[`isatty`](http://man7.org/linux/man-pages/man3/isatty.3.html) +function. +Unfortunately, this notoriously does not work well in Windows environments. To +work around that, the currently recommended solution is to use the +[`atty`](https://crates.io/crates/atty) +crate, which goes out of its way to get this as right as possible in Windows +environments. + +For example, in a command line application that exposes a `--color` flag, +your logic for how to enable colors might look like this: + +```rust,ignore +use atty; +use termcolor::{ColorChoice, StandardStream}; + +let preference = argv.get_flag("color").unwrap_or("auto"); +let choice = match preference { + "always" => ColorChoice::Always, + "ansi" => ColorChoice::AlwaysAnsi, + "auto" => { + if atty::is(atty::Stream::Stdout) { + ColorChoice::Auto + } else { + ColorChoice::Never + } + } + _ => ColorChoice::Never, +}; +let stdout = StandardStream::stdout(choice); +// ... write to stdout +``` + +Currently, `termcolor` does not provide anything to do this for you. */ #![deny(missing_docs)] -#[cfg(windows)] -extern crate wincolor; +// #[cfg(doctest)] +// use doc_comment::doctest; +// #[cfg(doctest)] +// doctest!("../README.md"); use std::env; use std::error; use std::fmt; use std::io::{self, Write}; use std::str::FromStr; +use std::sync::atomic::{AtomicBool, Ordering}; #[cfg(windows)] use std::sync::{Mutex, MutexGuard}; -use std::sync::atomic::{AtomicBool, Ordering}; + +#[cfg(windows)] +use winapi_util::console as wincon; /// This trait describes the behavior of writers that support colored output. pub trait WriteColor: io::Write { @@ -120,21 +173,33 @@ pub trait WriteColor: io::Write { } impl<'a, T: ?Sized + WriteColor> WriteColor for &'a mut T { - fn supports_color(&self) -> bool { (&**self).supports_color() } + fn supports_color(&self) -> bool { + (&**self).supports_color() + } fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { (&mut **self).set_color(spec) } - fn reset(&mut self) -> io::Result<()> { (&mut **self).reset() } - fn is_synchronous(&self) -> bool { (&**self).is_synchronous() } + fn reset(&mut self) -> io::Result<()> { + (&mut **self).reset() + } + fn is_synchronous(&self) -> bool { + (&**self).is_synchronous() + } } impl WriteColor for Box { - fn supports_color(&self) -> bool { (&**self).supports_color() } + fn supports_color(&self) -> bool { + (&**self).supports_color() + } fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { (&mut **self).set_color(spec) } - fn reset(&mut self) -> io::Result<()> { (&mut **self).reset() } - fn is_synchronous(&self) -> bool { (&**self).is_synchronous() } + fn reset(&mut self) -> io::Result<()> { + (&mut **self).reset() + } + fn is_synchronous(&self) -> bool { + (&**self).is_synchronous() + } } /// ColorChoice represents the color preferences of an end user. @@ -147,8 +212,8 @@ pub enum ColorChoice { /// than emitting ANSI color codes. AlwaysAnsi, /// Try to use colors, but don't force the issue. If the console isn't - /// available on Windows, or if TERM=dumb, for example, then don't use - /// colors. + /// available on Windows, or if TERM=dumb, or if `NO_COLOR` is defined, for + /// example, then don't use colors. Auto, /// Never emit colors. Never, @@ -156,35 +221,51 @@ pub enum ColorChoice { impl ColorChoice { /// Returns true if we should attempt to write colored output. - #[cfg(not(windows))] fn should_attempt_color(&self) -> bool { match *self { ColorChoice::Always => true, ColorChoice::AlwaysAnsi => true, ColorChoice::Never => false, - ColorChoice::Auto => { - match env::var("TERM") { - Err(_) => false, - Ok(k) => k != "dumb", - } - } + ColorChoice::Auto => self.env_allows_color(), } } - /// Returns true if we should attempt to write colored output. - #[cfg(windows)] - fn should_attempt_color(&self) -> bool { - match *self { - ColorChoice::Always => true, - ColorChoice::AlwaysAnsi => true, - ColorChoice::Never => false, - ColorChoice::Auto => { - match env::var("TERM") { - Err(_) => true, - Ok(k) => k != "dumb", + #[cfg(not(windows))] + fn env_allows_color(&self) -> bool { + match env::var_os("TERM") { + // If TERM isn't set, then we are in a weird environment that + // probably doesn't support colors. + None => return false, + Some(k) => { + if k == "dumb" { + return false; } } } + // If TERM != dumb, then the only way we don't allow colors at this + // point is if NO_COLOR is set. + if env::var_os("NO_COLOR").is_some() { + return false; + } + true + } + + #[cfg(windows)] + fn env_allows_color(&self) -> bool { + // On Windows, if TERM isn't set, then we shouldn't automatically + // assume that colors aren't allowed. This is unlike Unix environments + // where TERM is more rigorously set. + if let Some(k) = env::var_os("TERM") { + if k == "dumb" { + return false; + } + } + // If TERM != dumb, then the only way we don't allow colors at this + // point is if NO_COLOR is set. + if env::var_os("NO_COLOR").is_some() { + return false; + } + true } /// Returns true if this choice should forcefully use ANSI color codes. @@ -248,7 +329,7 @@ impl IoStandardStream { } } - fn lock(&self) -> IoStandardStreamLock { + fn lock(&self) -> IoStandardStreamLock<'_> { match *self { IoStandardStream::Stdout(ref s) => { IoStandardStreamLock::StdoutLock(s.lock()) @@ -341,7 +422,10 @@ enum WriterInner { NoColor(NoColor), Ansi(Ansi), #[cfg(windows)] - Windows { wtr: W, console: Mutex }, + Windows { + wtr: W, + console: Mutex, + }, } /// WriterInnerLock is a (limited) generic representation of a writer. It is @@ -356,7 +440,10 @@ enum WriterInnerLock<'a, W> { #[allow(dead_code)] Unreachable(::std::marker::PhantomData<&'a ()>), #[cfg(windows)] - Windows { wtr: W, console: MutexGuard<'a, wincolor::Console> }, + Windows { + wtr: W, + console: MutexGuard<'a, wincon::Console>, + }, } impl StandardStream { @@ -393,14 +480,14 @@ impl StandardStream { /// /// This method is **not reentrant**. It may panic if `lock` is called /// while a `StandardStreamLock` is still alive. - pub fn lock(&self) -> StandardStreamLock { + pub fn lock(&self) -> StandardStreamLock<'_> { StandardStreamLock::from_stream(self) } } impl<'a> StandardStreamLock<'a> { #[cfg(not(windows))] - fn from_stream(stream: &StandardStream) -> StandardStreamLock { + fn from_stream(stream: &StandardStream) -> StandardStreamLock<'_> { let locked = match *stream.wtr.get_ref() { WriterInner::NoColor(ref w) => { WriterInnerLock::NoColor(NoColor(w.0.lock())) @@ -443,10 +530,8 @@ impl BufferedStandardStream { /// The specific color/style settings can be configured when writing via /// the `WriteColor` trait. pub fn stdout(choice: ColorChoice) -> BufferedStandardStream { - let wtr = WriterInner::create( - StandardStreamType::StdoutBuffered, - choice, - ); + let wtr = + WriterInner::create(StandardStreamType::StdoutBuffered, choice); BufferedStandardStream { wtr: LossyStandardStream::new(wtr) } } @@ -459,10 +544,8 @@ impl BufferedStandardStream { /// The specific color/style settings can be configured when writing via /// the `WriteColor` trait. pub fn stderr(choice: ColorChoice) -> BufferedStandardStream { - let wtr = WriterInner::create( - StandardStreamType::StderrBuffered, - choice, - ); + let wtr = + WriterInner::create(StandardStreamType::StderrBuffered, choice); BufferedStandardStream { wtr: LossyStandardStream::new(wtr) } } } @@ -493,14 +576,15 @@ impl WriterInner { choice: ColorChoice, ) -> WriterInner { let mut con = match sty { - StandardStreamType::Stdout => wincolor::Console::stdout(), - StandardStreamType::Stderr => wincolor::Console::stderr(), - StandardStreamType::StdoutBuffered => wincolor::Console::stdout(), - StandardStreamType::StderrBuffered => wincolor::Console::stderr(), + StandardStreamType::Stdout => wincon::Console::stdout(), + StandardStreamType::Stderr => wincon::Console::stderr(), + StandardStreamType::StdoutBuffered => wincon::Console::stdout(), + StandardStreamType::StderrBuffered => wincon::Console::stderr(), }; - let is_console_virtual = con.as_mut().map(|con| { - con.set_virtual_terminal_processing(true).is_ok() - }).unwrap_or(false); + let is_console_virtual = con + .as_mut() + .map(|con| con.set_virtual_terminal_processing(true).is_ok()) + .unwrap_or(false); if choice.should_attempt_color() { if choice.should_ansi() || is_console_virtual { WriterInner::Ansi(Ansi(IoStandardStream::new(sty))) @@ -520,15 +604,21 @@ impl WriterInner { impl io::Write for StandardStream { #[inline] - fn write(&mut self, b: &[u8]) -> io::Result { self.wtr.write(b) } + fn write(&mut self, b: &[u8]) -> io::Result { + self.wtr.write(b) + } #[inline] - fn flush(&mut self) -> io::Result<()> { self.wtr.flush() } + fn flush(&mut self) -> io::Result<()> { + self.wtr.flush() + } } impl WriteColor for StandardStream { #[inline] - fn supports_color(&self) -> bool { self.wtr.supports_color() } + fn supports_color(&self) -> bool { + self.wtr.supports_color() + } #[inline] fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { @@ -536,23 +626,33 @@ impl WriteColor for StandardStream { } #[inline] - fn reset(&mut self) -> io::Result<()> { self.wtr.reset() } + fn reset(&mut self) -> io::Result<()> { + self.wtr.reset() + } #[inline] - fn is_synchronous(&self) -> bool { self.wtr.is_synchronous() } + fn is_synchronous(&self) -> bool { + self.wtr.is_synchronous() + } } impl<'a> io::Write for StandardStreamLock<'a> { #[inline] - fn write(&mut self, b: &[u8]) -> io::Result { self.wtr.write(b) } + fn write(&mut self, b: &[u8]) -> io::Result { + self.wtr.write(b) + } #[inline] - fn flush(&mut self) -> io::Result<()> { self.wtr.flush() } + fn flush(&mut self) -> io::Result<()> { + self.wtr.flush() + } } impl<'a> WriteColor for StandardStreamLock<'a> { #[inline] - fn supports_color(&self) -> bool { self.wtr.supports_color() } + fn supports_color(&self) -> bool { + self.wtr.supports_color() + } #[inline] fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { @@ -560,23 +660,33 @@ impl<'a> WriteColor for StandardStreamLock<'a> { } #[inline] - fn reset(&mut self) -> io::Result<()> { self.wtr.reset() } + fn reset(&mut self) -> io::Result<()> { + self.wtr.reset() + } #[inline] - fn is_synchronous(&self) -> bool { self.wtr.is_synchronous() } + fn is_synchronous(&self) -> bool { + self.wtr.is_synchronous() + } } impl io::Write for BufferedStandardStream { #[inline] - fn write(&mut self, b: &[u8]) -> io::Result { self.wtr.write(b) } + fn write(&mut self, b: &[u8]) -> io::Result { + self.wtr.write(b) + } #[inline] - fn flush(&mut self) -> io::Result<()> { self.wtr.flush() } + fn flush(&mut self) -> io::Result<()> { + self.wtr.flush() + } } impl WriteColor for BufferedStandardStream { #[inline] - fn supports_color(&self) -> bool { self.wtr.supports_color() } + fn supports_color(&self) -> bool { + self.wtr.supports_color() + } #[inline] fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { @@ -587,10 +697,14 @@ impl WriteColor for BufferedStandardStream { } #[inline] - fn reset(&mut self) -> io::Result<()> { self.wtr.reset() } + fn reset(&mut self) -> io::Result<()> { + self.wtr.reset() + } #[inline] - fn is_synchronous(&self) -> bool { self.wtr.is_synchronous() } + fn is_synchronous(&self) -> bool { + self.wtr.is_synchronous() + } } impl io::Write for WriterInner { @@ -656,7 +770,7 @@ impl WriteColor for WriterInner { WriterInner::NoColor(_) => false, WriterInner::Ansi(_) => false, #[cfg(windows)] - WriterInner::Windows {..} => true, + WriterInner::Windows { .. } => true, } } } @@ -727,7 +841,7 @@ impl<'a, W: io::Write> WriteColor for WriterInnerLock<'a, W> { WriterInnerLock::NoColor(_) => false, WriterInnerLock::Ansi(_) => false, #[cfg(windows)] - WriterInnerLock::Windows {..} => true, + WriterInnerLock::Windows { .. } => true, } } } @@ -747,7 +861,7 @@ pub struct BufferWriter { separator: Option>, color_choice: ColorChoice, #[cfg(windows)] - console: Option>, + console: Option>, } impl BufferWriter { @@ -777,14 +891,16 @@ impl BufferWriter { #[cfg(windows)] fn create(sty: StandardStreamType, choice: ColorChoice) -> BufferWriter { let mut con = match sty { - StandardStreamType::Stdout => wincolor::Console::stdout(), - StandardStreamType::Stderr => wincolor::Console::stderr(), - StandardStreamType::StdoutBuffered => wincolor::Console::stdout(), - StandardStreamType::StderrBuffered => wincolor::Console::stderr(), - }.ok(); - let is_console_virtual = con.as_mut().map(|con| { - con.set_virtual_terminal_processing(true).is_ok() - }).unwrap_or(false); + StandardStreamType::Stdout => wincon::Console::stdout(), + StandardStreamType::Stderr => wincon::Console::stderr(), + StandardStreamType::StdoutBuffered => wincon::Console::stdout(), + StandardStreamType::StderrBuffered => wincon::Console::stderr(), + } + .ok(); + let is_console_virtual = con + .as_mut() + .map(|con| con.set_virtual_terminal_processing(true).is_ok()) + .unwrap_or(false); // If we can enable ANSI on Windows, then we don't need the console // anymore. if is_console_virtual { @@ -873,7 +989,9 @@ impl BufferWriter { BufferInner::Windows(ref b) => { // We guarantee by construction that we have a console here. // Namely, a BufferWriter is the only way to produce a Buffer. - let console_mutex = self.console.as_ref() + let console_mutex = self + .console + .as_ref() .expect("got Windows buffer but have no Console"); let mut console = console_mutex.lock().unwrap(); b.print(&mut *console, &mut stream)?; @@ -1082,16 +1200,24 @@ pub struct NoColor(W); impl NoColor { /// Create a new writer that satisfies `WriteColor` but drops all color /// information. - pub fn new(wtr: W) -> NoColor { NoColor(wtr) } + pub fn new(wtr: W) -> NoColor { + NoColor(wtr) + } /// Consume this `NoColor` value and return the inner writer. - pub fn into_inner(self) -> W { self.0 } + pub fn into_inner(self) -> W { + self.0 + } /// Return a reference to the inner writer. - pub fn get_ref(&self) -> &W { &self.0 } + pub fn get_ref(&self) -> &W { + &self.0 + } /// Return a mutable reference to the inner writer. - pub fn get_mut(&mut self) -> &mut W { &mut self.0 } + pub fn get_mut(&mut self) -> &mut W { + &mut self.0 + } } impl io::Write for NoColor { @@ -1108,16 +1234,24 @@ impl io::Write for NoColor { impl WriteColor for NoColor { #[inline] - fn supports_color(&self) -> bool { false } + fn supports_color(&self) -> bool { + false + } #[inline] - fn set_color(&mut self, _: &ColorSpec) -> io::Result<()> { Ok(()) } + fn set_color(&mut self, _: &ColorSpec) -> io::Result<()> { + Ok(()) + } #[inline] - fn reset(&mut self) -> io::Result<()> { Ok(()) } + fn reset(&mut self) -> io::Result<()> { + Ok(()) + } #[inline] - fn is_synchronous(&self) -> bool { false } + fn is_synchronous(&self) -> bool { + false + } } /// Satisfies `WriteColor` using standard ANSI escape sequences. @@ -1126,16 +1260,24 @@ pub struct Ansi(W); impl Ansi { /// Create a new writer that satisfies `WriteColor` using standard ANSI /// escape sequences. - pub fn new(wtr: W) -> Ansi { Ansi(wtr) } + pub fn new(wtr: W) -> Ansi { + Ansi(wtr) + } /// Consume this `Ansi` value and return the inner writer. - pub fn into_inner(self) -> W { self.0 } + pub fn into_inner(self) -> W { + self.0 + } /// Return a reference to the inner writer. - pub fn get_ref(&self) -> &W { &self.0 } + pub fn get_ref(&self) -> &W { + &self.0 + } /// Return a mutable reference to the inner writer. - pub fn get_mut(&mut self) -> &mut W { &mut self.0 } + pub fn get_mut(&mut self) -> &mut W { + &mut self.0 + } } impl io::Write for Ansi { @@ -1152,14 +1294,24 @@ impl io::Write for Ansi { impl WriteColor for Ansi { #[inline] - fn supports_color(&self) -> bool { true } + fn supports_color(&self) -> bool { + true + } #[inline] fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { - self.reset()?; + if spec.reset { + self.reset()?; + } if spec.bold { self.write_str("\x1B[1m")?; } + if spec.dimmed { + self.write_str("\x1B[2m")?; + } + if spec.italic { + self.write_str("\x1B[3m")?; + } if spec.underline { self.write_str("\x1B[4m")?; } @@ -1178,7 +1330,9 @@ impl WriteColor for Ansi { } #[inline] - fn is_synchronous(&self) -> bool { false } + fn is_synchronous(&self) -> bool { + false + } } impl Ansi { @@ -1199,7 +1353,7 @@ impl Ansi { } else { self.write_str(concat!("\x1B[48;5;", $clr, "m")) } - } + }; } macro_rules! write_normal { ($clr:expr) => { @@ -1208,7 +1362,7 @@ impl Ansi { } else { self.write_str(concat!("\x1B[4", $clr, "m")) } - } + }; } macro_rules! write_var_ansi_code { ($pre:expr, $($code:expr),+) => {{ @@ -1328,10 +1482,7 @@ struct WindowsBuffer { impl WindowsBuffer { /// Create a new empty buffer for Windows console coloring. fn new() -> WindowsBuffer { - WindowsBuffer { - buf: vec![], - colors: vec![], - } + WindowsBuffer { buf: vec![], colors: vec![] } } /// Push the given color specification into this buffer. @@ -1347,7 +1498,7 @@ impl WindowsBuffer { /// for coloring. fn print( &self, - console: &mut wincolor::Console, + console: &mut wincon::Console, stream: &mut LossyStandardStream, ) -> io::Result<()> { let mut last = 0; @@ -1388,7 +1539,9 @@ impl io::Write for WindowsBuffer { #[cfg(windows)] impl WriteColor for WindowsBuffer { #[inline] - fn supports_color(&self) -> bool { true } + fn supports_color(&self) -> bool { + true + } #[inline] fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { @@ -1409,13 +1562,31 @@ impl WriteColor for WindowsBuffer { } /// A color specification. -#[derive(Clone, Debug, Default, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct ColorSpec { fg_color: Option, bg_color: Option, bold: bool, intense: bool, underline: bool, + dimmed: bool, + italic: bool, + reset: bool, +} + +impl Default for ColorSpec { + fn default() -> ColorSpec { + ColorSpec { + fg_color: None, + bg_color: None, + bold: false, + intense: false, + underline: false, + dimmed: false, + italic: false, + reset: true, + } + } } impl ColorSpec { @@ -1425,7 +1596,9 @@ impl ColorSpec { } /// Get the foreground color. - pub fn fg(&self) -> Option<&Color> { self.fg_color.as_ref() } + pub fn fg(&self) -> Option<&Color> { + self.fg_color.as_ref() + } /// Set the foreground color. pub fn set_fg(&mut self, color: Option) -> &mut ColorSpec { @@ -1434,7 +1607,9 @@ impl ColorSpec { } /// Get the background color. - pub fn bg(&self) -> Option<&Color> { self.bg_color.as_ref() } + pub fn bg(&self) -> Option<&Color> { + self.bg_color.as_ref() + } /// Set the background color. pub fn set_bg(&mut self, color: Option) -> &mut ColorSpec { @@ -1445,7 +1620,9 @@ impl ColorSpec { /// Get whether this is bold or not. /// /// Note that the bold setting has no effect in a Windows console. - pub fn bold(&self) -> bool { self.bold } + pub fn bold(&self) -> bool { + self.bold + } /// Set whether the text is bolded or not. /// @@ -1455,10 +1632,42 @@ impl ColorSpec { self } + /// Get whether this is dimmed or not. + /// + /// Note that the dimmed setting has no effect in a Windows console. + pub fn dimmed(&self) -> bool { + self.dimmed + } + + /// Set whether the text is dimmed or not. + /// + /// Note that the dimmed setting has no effect in a Windows console. + pub fn set_dimmed(&mut self, yes: bool) -> &mut ColorSpec { + self.dimmed = yes; + self + } + + /// Get whether this is italic or not. + /// + /// Note that the italic setting has no effect in a Windows console. + pub fn italic(&self) -> bool { + self.italic + } + + /// Set whether the text is italicized or not. + /// + /// Note that the italic setting has no effect in a Windows console. + pub fn set_italic(&mut self, yes: bool) -> &mut ColorSpec { + self.italic = yes; + self + } + /// Get whether this is underline or not. /// /// Note that the underline setting has no effect in a Windows console. - pub fn underline(&self) -> bool { self.underline } + pub fn underline(&self) -> bool { + self.underline + } /// Set whether the text is underlined or not. /// @@ -1468,6 +1677,33 @@ impl ColorSpec { self } + /// Get whether reset is enabled or not. + /// + /// reset is enabled by default. When disabled and using ANSI escape + /// sequences, a "reset" code will be emitted every time a `ColorSpec`'s + /// settings are applied. + /// + /// Note that the reset setting has no effect in a Windows console. + pub fn reset(&self) -> bool { + self.reset + } + + /// Set whether to reset the terminal whenever color settings are applied. + /// + /// reset is enabled by default. When disabled and using ANSI escape + /// sequences, a "reset" code will be emitted every time a `ColorSpec`'s + /// settings are applied. + /// + /// Typically this is useful if callers have a requirement to more + /// scrupulously manage the exact sequence of escape codes that are emitted + /// when using ANSI for colors. + /// + /// Note that the reset setting has no effect in a Windows console. + pub fn set_reset(&mut self, yes: bool) -> &mut ColorSpec { + self.reset = yes; + self + } + /// Get whether this is intense or not. /// /// On Unix-like systems, this will output the ANSI escape sequence @@ -1476,7 +1712,9 @@ impl ColorSpec { /// /// On Windows systems, this will output the ANSI escape sequence /// that will print a brighter version of the color specified. - pub fn intense(&self) -> bool { self.intense } + pub fn intense(&self) -> bool { + self.intense + } /// Set whether the text is intense or not. /// @@ -1493,8 +1731,13 @@ impl ColorSpec { /// Returns true if this color specification has no colors or styles. pub fn is_none(&self) -> bool { - self.fg_color.is_none() && self.bg_color.is_none() - && !self.bold && !self.underline + self.fg_color.is_none() + && self.bg_color.is_none() + && !self.bold + && !self.underline + && !self.dimmed + && !self.italic + && !self.intense } /// Clears this color specification so that it has no color/style settings. @@ -1503,14 +1746,14 @@ impl ColorSpec { self.bg_color = None; self.bold = false; self.underline = false; + self.intense = false; + self.dimmed = false; + self.italic = false; } /// Writes this color spec to the given Windows console. #[cfg(windows)] - fn write_console( - &self, - console: &mut wincolor::Console, - ) -> io::Result<()> { + fn write_console(&self, console: &mut wincon::Console) -> io::Result<()> { let fg_color = self.fg_color.and_then(|c| c.to_windows(self.intense)); if let Some((intense, color)) = fg_color { console.fg(intense, color)?; @@ -1562,39 +1805,39 @@ pub enum Color { } impl Color { - /// Translate this color to a wincolor::Color. + /// Translate this color to a wincon::Color. #[cfg(windows)] fn to_windows( self, intense: bool, - ) -> Option<(wincolor::Intense, wincolor::Color)> { - use wincolor::Intense::{Yes, No}; + ) -> Option<(wincon::Intense, wincon::Color)> { + use wincon::Intense::{No, Yes}; let color = match self { - Color::Black => wincolor::Color::Black, - Color::Blue => wincolor::Color::Blue, - Color::Green => wincolor::Color::Green, - Color::Red => wincolor::Color::Red, - Color::Cyan => wincolor::Color::Cyan, - Color::Magenta => wincolor::Color::Magenta, - Color::Yellow => wincolor::Color::Yellow, - Color::White => wincolor::Color::White, - Color::Ansi256(0) => return Some((No, wincolor::Color::Black)), - Color::Ansi256(1) => return Some((No, wincolor::Color::Red)), - Color::Ansi256(2) => return Some((No, wincolor::Color::Green)), - Color::Ansi256(3) => return Some((No, wincolor::Color::Yellow)), - Color::Ansi256(4) => return Some((No, wincolor::Color::Blue)), - Color::Ansi256(5) => return Some((No, wincolor::Color::Magenta)), - Color::Ansi256(6) => return Some((No, wincolor::Color::Cyan)), - Color::Ansi256(7) => return Some((No, wincolor::Color::White)), - Color::Ansi256(8) => return Some((Yes, wincolor::Color::Black)), - Color::Ansi256(9) => return Some((Yes, wincolor::Color::Red)), - Color::Ansi256(10) => return Some((Yes, wincolor::Color::Green)), - Color::Ansi256(11) => return Some((Yes, wincolor::Color::Yellow)), - Color::Ansi256(12) => return Some((Yes, wincolor::Color::Blue)), - Color::Ansi256(13) => return Some((Yes, wincolor::Color::Magenta)), - Color::Ansi256(14) => return Some((Yes, wincolor::Color::Cyan)), - Color::Ansi256(15) => return Some((Yes, wincolor::Color::White)), + Color::Black => wincon::Color::Black, + Color::Blue => wincon::Color::Blue, + Color::Green => wincon::Color::Green, + Color::Red => wincon::Color::Red, + Color::Cyan => wincon::Color::Cyan, + Color::Magenta => wincon::Color::Magenta, + Color::Yellow => wincon::Color::Yellow, + Color::White => wincon::Color::White, + Color::Ansi256(0) => return Some((No, wincon::Color::Black)), + Color::Ansi256(1) => return Some((No, wincon::Color::Red)), + Color::Ansi256(2) => return Some((No, wincon::Color::Green)), + Color::Ansi256(3) => return Some((No, wincon::Color::Yellow)), + Color::Ansi256(4) => return Some((No, wincon::Color::Blue)), + Color::Ansi256(5) => return Some((No, wincon::Color::Magenta)), + Color::Ansi256(6) => return Some((No, wincon::Color::Cyan)), + Color::Ansi256(7) => return Some((No, wincon::Color::White)), + Color::Ansi256(8) => return Some((Yes, wincon::Color::Black)), + Color::Ansi256(9) => return Some((Yes, wincon::Color::Red)), + Color::Ansi256(10) => return Some((Yes, wincon::Color::Green)), + Color::Ansi256(11) => return Some((Yes, wincon::Color::Yellow)), + Color::Ansi256(12) => return Some((Yes, wincon::Color::Blue)), + Color::Ansi256(13) => return Some((Yes, wincon::Color::Magenta)), + Color::Ansi256(14) => return Some((Yes, wincon::Color::Cyan)), + Color::Ansi256(15) => return Some((Yes, wincon::Color::White)), Color::Ansi256(_) => return None, Color::Rgb(_, _, _) => return None, Color::__Nonexhaustive => unreachable!(), @@ -1641,11 +1884,9 @@ impl Color { } else if codes.len() == 3 { let mut v = vec![]; for code in codes { - let n = parse_number(code).ok_or_else(|| { - ParseColorError { - kind: ParseColorErrorKind::InvalidRgb, - given: s.to_string(), - } + let n = parse_number(code).ok_or_else(|| ParseColorError { + kind: ParseColorErrorKind::InvalidRgb, + given: s.to_string(), })?; v.push(n); } @@ -1682,7 +1923,9 @@ enum ParseColorErrorKind { impl ParseColorError { /// Return the string that couldn't be parsed as a valid color. - pub fn invalid(&self) -> &str { &self.given } + pub fn invalid(&self) -> &str { + &self.given + } } impl error::Error for ParseColorError { @@ -1697,25 +1940,29 @@ impl error::Error for ParseColorError { } impl fmt::Display for ParseColorError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use self::ParseColorErrorKind::*; match self.kind { - InvalidName => { - write!(f, "unrecognized color name '{}'. Choose from: \ - black, blue, green, red, cyan, magenta, yellow, \ - white", - self.given) - } - InvalidAnsi256 => { - write!(f, "unrecognized ansi256 color number, \ - should be '[0-255]' (or a hex number), but is '{}'", - self.given) - } - InvalidRgb => { - write!(f, "unrecognized RGB color triple, \ - should be '[0-255],[0-255],[0-255]' (or a hex \ - triple), but is '{}'", self.given) - } + InvalidName => write!( + f, + "unrecognized color name '{}'. Choose from: \ + black, blue, green, red, cyan, magenta, yellow, \ + white", + self.given + ), + InvalidAnsi256 => write!( + f, + "unrecognized ansi256 color number, \ + should be '[0-255]' (or a hex number), but is '{}'", + self.given + ), + InvalidRgb => write!( + f, + "unrecognized RGB color triple, \ + should be '[0-255],[0-255],[0-255]' (or a hex \ + triple), but is '{}'", + self.given + ), } } } @@ -1752,9 +1999,8 @@ impl LossyStandardStream { #[cfg(windows)] fn new(wtr: W) -> LossyStandardStream { - let is_console = - wincolor::Console::stdout().is_ok() - || wincolor::Console::stderr().is_ok(); + let is_console = wincon::Console::stdout().is_ok() + || wincon::Console::stderr().is_ok(); LossyStandardStream { wtr: wtr, is_console: is_console } } @@ -1774,12 +2020,18 @@ impl LossyStandardStream { } impl WriteColor for LossyStandardStream { - fn supports_color(&self) -> bool { self.wtr.supports_color() } + fn supports_color(&self) -> bool { + self.wtr.supports_color() + } fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { self.wtr.set_color(spec) } - fn reset(&mut self) -> io::Result<()> { self.wtr.reset() } - fn is_synchronous(&self) -> bool { self.wtr.is_synchronous() } + fn reset(&mut self) -> io::Result<()> { + self.wtr.reset() + } + fn is_synchronous(&self) -> bool { + self.wtr.is_synchronous() + } } impl io::Write for LossyStandardStream { @@ -1817,7 +2069,8 @@ fn write_lossy_utf8(mut w: W, buf: &[u8]) -> io::Result { #[cfg(test)] mod tests { use super::{ - Ansi, Color, ParseColorError, ParseColorErrorKind, StandardStream, + Ansi, Color, ColorSpec, ParseColorError, ParseColorErrorKind, + StandardStream, WriteColor, }; fn assert_is_send() {} @@ -1848,10 +2101,13 @@ mod tests { #[test] fn test_256_parse_err_out_of_range() { let color = "256".parse::(); - assert_eq!(color, Err(ParseColorError { - kind: ParseColorErrorKind::InvalidAnsi256, - given: "256".to_string(), - })); + assert_eq!( + color, + Err(ParseColorError { + kind: ParseColorErrorKind::InvalidAnsi256, + given: "256".to_string(), + }) + ); } #[test] @@ -1872,25 +2128,34 @@ mod tests { #[test] fn test_rgb_parse_err_out_of_range() { let color = "0,0,256".parse::(); - assert_eq!(color, Err(ParseColorError { - kind: ParseColorErrorKind::InvalidRgb, - given: "0,0,256".to_string(), - })); + assert_eq!( + color, + Err(ParseColorError { + kind: ParseColorErrorKind::InvalidRgb, + given: "0,0,256".to_string(), + }) + ); } #[test] fn test_rgb_parse_err_bad_format() { let color = "0,0".parse::(); - assert_eq!(color, Err(ParseColorError { - kind: ParseColorErrorKind::InvalidRgb, - given: "0,0".to_string(), - })); + assert_eq!( + color, + Err(ParseColorError { + kind: ParseColorErrorKind::InvalidRgb, + given: "0,0".to_string(), + }) + ); let color = "not_a_color".parse::(); - assert_eq!(color, Err(ParseColorError { - kind: ParseColorErrorKind::InvalidName, - given: "not_a_color".to_string(), - })); + assert_eq!( + color, + Err(ParseColorError { + kind: ParseColorErrorKind::InvalidName, + given: "not_a_color".to_string(), + }) + ); } #[test] @@ -1900,6 +2165,24 @@ mod tests { assert_eq!(buf.0, b"\x1B[38;2;254;253;255m"); } + #[test] + fn test_reset() { + let spec = ColorSpec::new(); + let mut buf = Ansi::new(vec![]); + buf.set_color(&spec).unwrap(); + assert_eq!(buf.0, b"\x1B[0m"); + } + + #[test] + fn test_no_reset() { + let mut spec = ColorSpec::new(); + spec.set_reset(false); + + let mut buf = Ansi::new(vec![]); + buf.set_color(&spec).unwrap(); + assert_eq!(buf.0, b""); + } + #[test] fn test_var_ansi_write_256() { let mut buf = Ansi::new(vec![]); @@ -1910,4 +2193,54 @@ mod tests { let _ = buf.write_color(false, &Color::Ansi256(208), false); assert_eq!(buf.0, b"\x1B[48;5;208m"); } + + fn all_attributes() -> Vec { + let mut result = vec![]; + for fg in vec![None, Some(Color::Red)] { + for bg in vec![None, Some(Color::Red)] { + for bold in vec![false, true] { + for underline in vec![false, true] { + for intense in vec![false, true] { + for italic in vec![false, true] { + for dimmed in vec![false, true] { + let mut color = ColorSpec::new(); + color.set_fg(fg); + color.set_bg(bg); + color.set_bold(bold); + color.set_underline(underline); + color.set_intense(intense); + color.set_dimmed(dimmed); + color.set_italic(italic); + result.push(color); + } + } + } + } + } + } + } + result + } + + #[test] + fn test_is_none() { + for (i, color) in all_attributes().iter().enumerate() { + assert_eq!( + i == 0, + color.is_none(), + "{:?} => {}", + color, + color.is_none() + ) + } + } + + #[test] + fn test_clear() { + for color in all_attributes() { + let mut color1 = color.clone(); + color1.clear(); + assert!(color1.is_none(), "{:?} => {:?}", color, color1); + } + } } diff --git a/third_party/rust/wincolor/.cargo-checksum.json b/third_party/rust/wincolor/.cargo-checksum.json deleted file mode 100644 index 98f2c73fe1e3..000000000000 --- a/third_party/rust/wincolor/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"52b63d0526a0afb7ca1c53d9b3fc712346a30772bdb2d79faa9c4903d68696fc","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"f2e0aea03834f9bf3bede2d5a0371f30fc7f6c8e9bdb136b810f21360e05fa39","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","src/lib.rs":"c69a94806e052cd540d2eeb9e6c92ca66c6f76436903296af33107c5106401fa","src/win.rs":"c63ed910831fcaa22e27210619bc645cd4973ed9fab4aa1a164ef986f0f92772"},"package":"96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"} \ No newline at end of file diff --git a/third_party/rust/wincolor/COPYING b/third_party/rust/wincolor/COPYING deleted file mode 100644 index bb9c20a094e4..000000000000 --- a/third_party/rust/wincolor/COPYING +++ /dev/null @@ -1,3 +0,0 @@ -This project is dual-licensed under the Unlicense and MIT licenses. - -You may use this code under the terms of either license. diff --git a/third_party/rust/wincolor/Cargo.toml b/third_party/rust/wincolor/Cargo.toml deleted file mode 100644 index b92d03d149ce..000000000000 --- a/third_party/rust/wincolor/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "wincolor" -version = "1.0.2" -authors = ["Andrew Gallant "] -description = "A simple Windows specific API for controlling text color in a Windows console.\n" -homepage = "https://github.com/BurntSushi/termcolor/tree/master/wincolor" -documentation = "https://docs.rs/wincolor" -readme = "README.md" -keywords = ["windows", "win", "color", "ansi", "console"] -license = "Unlicense OR MIT" -repository = "https://github.com/BurntSushi/termcolor/tree/master/wincolor" - -[lib] -name = "wincolor" -bench = false -[dependencies.winapi] -version = "0.3" -features = ["minwindef", "wincon"] - -[dependencies.winapi-util] -version = "0.1.1" diff --git a/third_party/rust/wincolor/LICENSE-MIT b/third_party/rust/wincolor/LICENSE-MIT deleted file mode 100644 index 3b0a5dc09c1e..000000000000 --- a/third_party/rust/wincolor/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Andrew Gallant - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/third_party/rust/wincolor/README.md b/third_party/rust/wincolor/README.md deleted file mode 100644 index cc780340e184..000000000000 --- a/third_party/rust/wincolor/README.md +++ /dev/null @@ -1,44 +0,0 @@ -wincolor -======== -A simple Windows specific API for controlling text color in a Windows console. -The purpose of this crate is to expose the full inflexibility of the Windows -console without any platform independent abstraction. - -[![Windows build status](https://ci.appveyor.com/api/projects/status/github/BurntSushi/ripgrep?svg=true)](https://ci.appveyor.com/project/BurntSushi/ripgrep) -[![](https://img.shields.io/crates/v/wincolor.svg)](https://crates.io/crates/wincolor) - -Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org). - -### Documentation - -[https://docs.rs/wincolor](https://docs.rs/wincolor) - -### Usage - -Add this to your `Cargo.toml`: - -```toml -[dependencies] -wincolor = "0.1" -``` - -and this to your crate root: - -```rust -extern crate wincolor; -``` - -### Example - -This is a simple example that shows how to write text with a foreground color -of cyan and the intense attribute set: - -```rust -use wincolor::{Console, Color, Intense}; - -let mut con = Console::stdout().unwrap(); -con.fg(Intense::Yes, Color::Cyan).unwrap(); -println!("This text will be intense cyan."); -con.reset().unwrap(); -println!("This text will be normal."); -``` diff --git a/third_party/rust/wincolor/UNLICENSE b/third_party/rust/wincolor/UNLICENSE deleted file mode 100644 index 68a49daad8ff..000000000000 --- a/third_party/rust/wincolor/UNLICENSE +++ /dev/null @@ -1,24 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to diff --git a/third_party/rust/wincolor/src/lib.rs b/third_party/rust/wincolor/src/lib.rs deleted file mode 100644 index 58dbbb6ef1ec..000000000000 --- a/third_party/rust/wincolor/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -/*! -This crate provides a safe and simple Windows specific API to control -text attributes in the Windows console. Text attributes are limited to -foreground/background colors, as well as whether to make colors intense or not. - -Note that on non-Windows platforms, this crate is empty but will compile. - -# Example - -```no_run -# #[cfg(windows)] -# { -use wincolor::{Console, Color, Intense}; - -let mut con = Console::stdout().unwrap(); -con.fg(Intense::Yes, Color::Cyan).unwrap(); -println!("This text will be intense cyan."); -con.reset().unwrap(); -println!("This text will be normal."); -# } -``` -*/ - -#![deny(missing_docs)] - -#[cfg(windows)] -extern crate winapi; -#[cfg(windows)] -extern crate winapi_util; - -#[cfg(windows)] -pub use win::*; - -#[cfg(windows)] -mod win; diff --git a/third_party/rust/wincolor/src/win.rs b/third_party/rust/wincolor/src/win.rs deleted file mode 100644 index 2115d1275b14..000000000000 --- a/third_party/rust/wincolor/src/win.rs +++ /dev/null @@ -1,261 +0,0 @@ -use std::io; - -use winapi::shared::minwindef::{WORD}; -use winapi::um::wincon::{ - self, - FOREGROUND_BLUE as FG_BLUE, - FOREGROUND_GREEN as FG_GREEN, - FOREGROUND_RED as FG_RED, - FOREGROUND_INTENSITY as FG_INTENSITY, -}; -use winapi_util as winutil; - -const FG_CYAN: WORD = FG_BLUE | FG_GREEN; -const FG_MAGENTA: WORD = FG_BLUE | FG_RED; -const FG_YELLOW: WORD = FG_GREEN | FG_RED; -const FG_WHITE: WORD = FG_BLUE | FG_GREEN | FG_RED; - -/// A Windows console. -/// -/// This represents a very limited set of functionality available to a Windows -/// console. In particular, it can only change text attributes such as color -/// and intensity. -/// -/// There is no way to "write" to this console. Simply write to -/// stdout or stderr instead, while interleaving instructions to the console -/// to change text attributes. -/// -/// A common pitfall when using a console is to forget to flush writes to -/// stdout before setting new text attributes. -#[derive(Debug)] -pub struct Console { - kind: HandleKind, - start_attr: TextAttributes, - cur_attr: TextAttributes, -} - -#[derive(Clone, Copy, Debug)] -enum HandleKind { - Stdout, - Stderr, -} - -impl HandleKind { - fn handle(&self) -> winutil::HandleRef { - match *self { - HandleKind::Stdout => winutil::HandleRef::stdout(), - HandleKind::Stderr => winutil::HandleRef::stderr(), - } - } -} - -impl Console { - /// Get a console for a standard I/O stream. - fn create_for_stream(kind: HandleKind) -> io::Result { - let h = kind.handle(); - let info = winutil::console::screen_buffer_info(&h)?; - let attr = TextAttributes::from_word(info.attributes()); - Ok(Console { - kind: kind, - start_attr: attr, - cur_attr: attr, - }) - } - - /// Create a new Console to stdout. - /// - /// If there was a problem creating the console, then an error is returned. - pub fn stdout() -> io::Result { - Self::create_for_stream(HandleKind::Stdout) - } - - /// Create a new Console to stderr. - /// - /// If there was a problem creating the console, then an error is returned. - pub fn stderr() -> io::Result { - Self::create_for_stream(HandleKind::Stderr) - } - - /// Applies the current text attributes. - fn set(&mut self) -> io::Result<()> { - winutil::console::set_text_attributes( - self.kind.handle(), - self.cur_attr.to_word(), - ) - } - - /// Apply the given intensity and color attributes to the console - /// foreground. - /// - /// If there was a problem setting attributes on the console, then an error - /// is returned. - pub fn fg(&mut self, intense: Intense, color: Color) -> io::Result<()> { - self.cur_attr.fg_color = color; - self.cur_attr.fg_intense = intense; - self.set() - } - - /// Apply the given intensity and color attributes to the console - /// background. - /// - /// If there was a problem setting attributes on the console, then an error - /// is returned. - pub fn bg(&mut self, intense: Intense, color: Color) -> io::Result<()> { - self.cur_attr.bg_color = color; - self.cur_attr.bg_intense = intense; - self.set() - } - - /// Reset the console text attributes to their original settings. - /// - /// The original settings correspond to the text attributes on the console - /// when this `Console` value was created. - /// - /// If there was a problem setting attributes on the console, then an error - /// is returned. - pub fn reset(&mut self) -> io::Result<()> { - self.cur_attr = self.start_attr; - self.set() - } - - /// Toggle virtual terminal processing. - /// - /// This method attempts to toggle virtual terminal processing for this - /// console. If there was a problem toggling it, then an error returned. - /// On success, the caller may assume that toggling it was successful. - /// - /// When virtual terminal processing is enabled, characters emitted to the - /// console are parsed for VT100 and similar control character sequences - /// that control color and other similar operations. - pub fn set_virtual_terminal_processing( - &mut self, - yes: bool, - ) -> io::Result<()> { - let vt = wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING; - - let handle = self.kind.handle(); - let old_mode = winutil::console::mode(&handle)?; - let new_mode = - if yes { - old_mode | vt - } else { - old_mode & !vt - }; - if old_mode == new_mode { - return Ok(()); - } - winutil::console::set_mode(&handle, new_mode) - } -} - -/// A representation of text attributes for the Windows console. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -struct TextAttributes { - fg_color: Color, - fg_intense: Intense, - bg_color: Color, - bg_intense: Intense, -} - -impl TextAttributes { - fn to_word(&self) -> WORD { - let mut w = 0; - w |= self.fg_color.to_fg(); - w |= self.fg_intense.to_fg(); - w |= self.bg_color.to_bg(); - w |= self.bg_intense.to_bg(); - w - } - - fn from_word(word: WORD) -> TextAttributes { - TextAttributes { - fg_color: Color::from_fg(word), - fg_intense: Intense::from_fg(word), - bg_color: Color::from_bg(word), - bg_intense: Intense::from_bg(word), - } - } -} - -/// Whether to use intense colors or not. -#[allow(missing_docs)] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Intense { - Yes, - No, -} - -impl Intense { - fn to_bg(&self) -> WORD { - self.to_fg() << 4 - } - - fn from_bg(word: WORD) -> Intense { - Intense::from_fg(word >> 4) - } - - fn to_fg(&self) -> WORD { - match *self { - Intense::No => 0, - Intense::Yes => FG_INTENSITY, - } - } - - fn from_fg(word: WORD) -> Intense { - if word & FG_INTENSITY > 0 { - Intense::Yes - } else { - Intense::No - } - } -} - -/// The set of available colors for use with a Windows console. -#[allow(missing_docs)] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Color { - Black, - Blue, - Green, - Red, - Cyan, - Magenta, - Yellow, - White, -} - -impl Color { - fn to_bg(&self) -> WORD { - self.to_fg() << 4 - } - - fn from_bg(word: WORD) -> Color { - Color::from_fg(word >> 4) - } - - fn to_fg(&self) -> WORD { - match *self { - Color::Black => 0, - Color::Blue => FG_BLUE, - Color::Green => FG_GREEN, - Color::Red => FG_RED, - Color::Cyan => FG_CYAN, - Color::Magenta => FG_MAGENTA, - Color::Yellow => FG_YELLOW, - Color::White => FG_WHITE, - } - } - - fn from_fg(word: WORD) -> Color { - match word & 0b111 { - FG_BLUE => Color::Blue, - FG_GREEN => Color::Green, - FG_RED => Color::Red, - FG_CYAN => Color::Cyan, - FG_MAGENTA => Color::Magenta, - FG_YELLOW => Color::Yellow, - FG_WHITE => Color::White, - _ => Color::Black, - } - } -}