Merge buffered destination into raw destination

This commit is contained in:
Oli Scherer 2023-07-26 14:56:34 +00:00
parent 339890e186
commit 00074698a7

View File

@ -36,8 +36,8 @@ use std::io::prelude::*;
use std::io::{self, IsTerminal}; use std::io::{self, IsTerminal};
use std::iter; use std::iter;
use std::path::Path; use std::path::Path;
use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream}; use termcolor::{Ansi, Buffer, BufferWriter, ColorChoice, ColorSpec, StandardStream};
use termcolor::{Buffer, Color, WriteColor}; use termcolor::{Color, WriteColor};
/// Default column width, used in tests and when terminal dimensions cannot be determined. /// Default column width, used in tests and when terminal dimensions cannot be determined.
const DEFAULT_COLUMN_WIDTH: usize = 140; const DEFAULT_COLUMN_WIDTH: usize = 140;
@ -2604,15 +2604,44 @@ fn emit_to_destination(
pub enum Destination { pub enum Destination {
Terminal(StandardStream), Terminal(StandardStream),
Buffered(BufferWriter),
Raw(Box<(dyn WriteColor + Send)>), Raw(Box<(dyn WriteColor + Send)>),
} }
pub enum WritableDst<'a> { pub enum WritableDst<'a> {
Buffered(&'a mut BufferWriter, Buffer),
Raw(&'a mut (dyn WriteColor + Send)), Raw(&'a mut (dyn WriteColor + Send)),
} }
struct Buffy {
buffer_writer: BufferWriter,
buffer: Buffer,
}
impl Write for Buffy {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buffer.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.buffer_writer.print(&self.buffer)?;
self.buffer.clear();
Ok(())
}
}
impl WriteColor for Buffy {
fn supports_color(&self) -> bool {
self.buffer.supports_color()
}
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
self.buffer.set_color(spec)
}
fn reset(&mut self) -> io::Result<()> {
self.buffer.reset()
}
}
impl Destination { impl Destination {
fn from_stderr(color: ColorConfig) -> Destination { fn from_stderr(color: ColorConfig) -> Destination {
let choice = color.to_color_choice(); let choice = color.to_color_choice();
@ -2625,17 +2654,15 @@ impl Destination {
if cfg!(windows) { if cfg!(windows) {
Terminal(StandardStream::stderr(choice)) Terminal(StandardStream::stderr(choice))
} else { } else {
Buffered(BufferWriter::stderr(choice)) let buffer_writer = BufferWriter::stderr(choice);
let buffer = buffer_writer.buffer();
Raw(Box::new(Buffy { buffer_writer, buffer }))
} }
} }
fn writable(&mut self) -> WritableDst<'_> { fn writable(&mut self) -> WritableDst<'_> {
match *self { match *self {
Destination::Terminal(ref mut t) => WritableDst::Raw(t), Destination::Terminal(ref mut t) => WritableDst::Raw(t),
Destination::Buffered(ref mut t) => {
let buf = t.buffer();
WritableDst::Buffered(t, buf)
}
Destination::Raw(ref mut t) => WritableDst::Raw(t), Destination::Raw(ref mut t) => WritableDst::Raw(t),
} }
} }
@ -2643,7 +2670,6 @@ impl Destination {
fn supports_color(&self) -> bool { fn supports_color(&self) -> bool {
match *self { match *self {
Self::Terminal(ref stream) => stream.supports_color(), Self::Terminal(ref stream) => stream.supports_color(),
Self::Buffered(ref buffer) => buffer.buffer().supports_color(),
Self::Raw(ref writer) => writer.supports_color(), Self::Raw(ref writer) => writer.supports_color(),
} }
} }
@ -2702,14 +2728,12 @@ impl<'a> WritableDst<'a> {
fn set_color(&mut self, color: &ColorSpec) -> io::Result<()> { fn set_color(&mut self, color: &ColorSpec) -> io::Result<()> {
match *self { match *self {
WritableDst::Buffered(_, ref mut t) => t.set_color(color),
WritableDst::Raw(ref mut t) => t.set_color(color), WritableDst::Raw(ref mut t) => t.set_color(color),
} }
} }
fn reset(&mut self) -> io::Result<()> { fn reset(&mut self) -> io::Result<()> {
match *self { match *self {
WritableDst::Buffered(_, ref mut t) => t.reset(),
WritableDst::Raw(ref mut t) => t.reset(), WritableDst::Raw(ref mut t) => t.reset(),
} }
} }
@ -2718,14 +2742,12 @@ impl<'a> WritableDst<'a> {
impl<'a> Write for WritableDst<'a> { impl<'a> Write for WritableDst<'a> {
fn write(&mut self, bytes: &[u8]) -> io::Result<usize> { fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
match *self { match *self {
WritableDst::Buffered(_, ref mut buf) => buf.write(bytes),
WritableDst::Raw(ref mut w) => w.write(bytes), WritableDst::Raw(ref mut w) => w.write(bytes),
} }
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
match *self { match *self {
WritableDst::Buffered(_, ref mut buf) => buf.flush(),
WritableDst::Raw(ref mut w) => w.flush(), WritableDst::Raw(ref mut w) => w.flush(),
} }
} }
@ -2733,9 +2755,7 @@ impl<'a> Write for WritableDst<'a> {
impl<'a> Drop for WritableDst<'a> { impl<'a> Drop for WritableDst<'a> {
fn drop(&mut self) { fn drop(&mut self) {
if let WritableDst::Buffered(ref mut dst, ref mut buf) = self { self.flush().unwrap()
drop(dst.print(buf));
}
} }
} }