mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 12:58:54 -05:00
perf: don't allocate so much in runtime/colors.rs (#21957)
This commit is contained in:
parent
b142c81721
commit
028f854468
1 changed files with 88 additions and 28 deletions
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::fmt::Write as _;
|
||||||
use std::io::IsTerminal;
|
use std::io::IsTerminal;
|
||||||
use std::io::Write;
|
|
||||||
use termcolor::Ansi;
|
use termcolor::Ansi;
|
||||||
use termcolor::Color::Ansi256;
|
use termcolor::Color::Ansi256;
|
||||||
use termcolor::Color::Black;
|
use termcolor::Color::Black;
|
||||||
|
@ -43,121 +43,181 @@ pub fn enable_ansi() {
|
||||||
BufferWriter::stdout(ColorChoice::AlwaysAnsi);
|
BufferWriter::stdout(ColorChoice::AlwaysAnsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style<S: AsRef<str>>(s: S, colorspec: ColorSpec) -> impl fmt::Display {
|
/// A struct that can adapt a `fmt::Write` to a `std::io::Write`. If anything
|
||||||
if !use_color() {
|
/// that can not be represented as UTF-8 is written to this writer, it will
|
||||||
return String::from(s.as_ref());
|
/// return an error.
|
||||||
|
struct StdFmtStdIoWriter<'a>(&'a mut dyn fmt::Write);
|
||||||
|
|
||||||
|
impl std::io::Write for StdFmtStdIoWriter<'_> {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||||
|
let str = std::str::from_utf8(buf).map_err(|_| {
|
||||||
|
std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"failed to convert bytes to str",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
match self.0.write_str(str) {
|
||||||
|
Ok(_) => Ok(buf.len()),
|
||||||
|
Err(_) => Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"failed to write to fmt::Write",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
let mut v = Vec::new();
|
|
||||||
let mut ansi_writer = Ansi::new(&mut v);
|
|
||||||
ansi_writer.set_color(&colorspec).unwrap();
|
|
||||||
ansi_writer.write_all(s.as_ref().as_bytes()).unwrap();
|
|
||||||
ansi_writer.reset().unwrap();
|
|
||||||
String::from_utf8_lossy(&v).into_owned()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn red_bold<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
/// A struct that can adapt a `std::io::Write` to a `fmt::Write`.
|
||||||
|
struct StdIoStdFmtWriter<'a>(&'a mut dyn std::io::Write);
|
||||||
|
|
||||||
|
impl fmt::Write for StdIoStdFmtWriter<'_> {
|
||||||
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
|
self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Style<I: fmt::Display> {
|
||||||
|
colorspec: ColorSpec,
|
||||||
|
inner: I,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: fmt::Display> fmt::Display for Style<I> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
if !use_color() {
|
||||||
|
return fmt::Display::fmt(&self.inner, f);
|
||||||
|
}
|
||||||
|
let mut ansi_writer = Ansi::new(StdFmtStdIoWriter(f));
|
||||||
|
ansi_writer
|
||||||
|
.set_color(&self.colorspec)
|
||||||
|
.map_err(|_| fmt::Error)?;
|
||||||
|
write!(StdIoStdFmtWriter(&mut ansi_writer), "{}", self.inner)?;
|
||||||
|
ansi_writer.reset().map_err(|_| fmt::Error)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn style<'a>(
|
||||||
|
s: impl fmt::Display + 'a,
|
||||||
|
colorspec: ColorSpec,
|
||||||
|
) -> impl fmt::Display + 'a {
|
||||||
|
Style {
|
||||||
|
colorspec,
|
||||||
|
inner: s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn red_bold<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Red)).set_bold(true);
|
style_spec.set_fg(Some(Red)).set_bold(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn green_bold<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn green_bold<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Green)).set_bold(true);
|
style_spec.set_fg(Some(Green)).set_bold(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn italic<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn italic<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_italic(true);
|
style_spec.set_italic(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn italic_gray<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn italic_gray<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Ansi256(8))).set_italic(true);
|
style_spec.set_fg(Some(Ansi256(8))).set_italic(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn italic_bold<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn italic_bold<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_bold(true).set_italic(true);
|
style_spec.set_bold(true).set_italic(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn white_on_red<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn white_on_red<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_bg(Some(Red)).set_fg(Some(White));
|
style_spec.set_bg(Some(Red)).set_fg(Some(White));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn black_on_green<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn black_on_green<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_bg(Some(Green)).set_fg(Some(Black));
|
style_spec.set_bg(Some(Green)).set_fg(Some(Black));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn yellow<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn yellow<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Yellow));
|
style_spec.set_fg(Some(Yellow));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cyan<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn cyan<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Cyan));
|
style_spec.set_fg(Some(Cyan));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cyan_with_underline<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn cyan_with_underline<'a>(
|
||||||
|
s: impl fmt::Display + 'a,
|
||||||
|
) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Cyan)).set_underline(true);
|
style_spec.set_fg(Some(Cyan)).set_underline(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cyan_bold<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn cyan_bold<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Cyan)).set_bold(true);
|
style_spec.set_fg(Some(Cyan)).set_bold(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn magenta<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn magenta<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Magenta));
|
style_spec.set_fg(Some(Magenta));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn red<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn red<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Red));
|
style_spec.set_fg(Some(Red));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn green<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn green<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Green));
|
style_spec.set_fg(Some(Green));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bold<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn bold<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_bold(true);
|
style_spec.set_bold(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gray<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn gray<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Ansi256(245)));
|
style_spec.set_fg(Some(Ansi256(245)));
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intense_blue<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn intense_blue<'a>(s: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec.set_fg(Some(Blue)).set_intense(true);
|
style_spec.set_fg(Some(Blue)).set_intense(true);
|
||||||
style(s, style_spec)
|
style(s, style_spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn white_bold_on_red<S: AsRef<str>>(s: S) -> impl fmt::Display {
|
pub fn white_bold_on_red<'a>(
|
||||||
|
s: impl fmt::Display + 'a,
|
||||||
|
) -> impl fmt::Display + 'a {
|
||||||
let mut style_spec = ColorSpec::new();
|
let mut style_spec = ColorSpec::new();
|
||||||
style_spec
|
style_spec
|
||||||
.set_bold(true)
|
.set_bold(true)
|
||||||
|
|
Loading…
Reference in a new issue