Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 53 additions & 20 deletions src/process/terminalsource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ enum TerminalInner {
TestWriter(TestWriter, ColorChoice),
}

impl TerminalInner {
fn as_write(&mut self) -> &mut dyn io::Write {
match self {
TerminalInner::StandardStream(s, _) => s,
#[cfg(feature = "test")]
TerminalInner::TestWriter(w, _) => w,
}
}
}

pub struct ColorableTerminalLocked {
// Must drop the lock before the guard, as the guard borrows from inner.
locked: TerminalInnerLocked,
Expand All @@ -83,6 +93,16 @@ enum TerminalInnerLocked {
TestWriter(TestWriterLock<'static>),
}

impl TerminalInnerLocked {
fn as_write(&mut self) -> &mut dyn io::Write {
match self {
TerminalInnerLocked::StandardStream(s) => s,
#[cfg(feature = "test")]
TerminalInnerLocked::TestWriter(w) => w,
}
}
}

impl ColorableTerminal {
/// A terminal that supports colorisation of a stream.
/// If `RUSTUP_TERM_COLOR` is set to `always`, or if the stream is a tty and
Expand Down Expand Up @@ -202,37 +222,50 @@ pub enum Attr {

impl io::Write for ColorableTerminal {
fn write(&mut self, buf: &[u8]) -> std::result::Result<usize, io::Error> {
match self.inner.lock().unwrap().deref_mut() {
TerminalInner::StandardStream(s, _) => s.write(buf),
#[cfg(feature = "test")]
TerminalInner::TestWriter(w, _) => w.write(buf),
}
let mut locked = self.inner.lock().unwrap();
locked.deref_mut().as_write().write(buf)
}

fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
let mut locked = self.inner.lock().unwrap();
locked.deref_mut().as_write().write_vectored(bufs)
}

fn flush(&mut self) -> std::result::Result<(), io::Error> {
match self.inner.lock().unwrap().deref_mut() {
TerminalInner::StandardStream(s, _) => s.flush(),
#[cfg(feature = "test")]
TerminalInner::TestWriter(w, _) => w.flush(),
}
let mut locked = self.inner.lock().unwrap();
locked.deref_mut().as_write().flush()
}

fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
let mut locked = self.inner.lock().unwrap();
locked.deref_mut().as_write().write_all(buf)
}

fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> {
let mut locked = self.inner.lock().unwrap();
locked.deref_mut().as_write().write_fmt(args)
}
}

impl io::Write for ColorableTerminalLocked {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match &mut self.locked {
TerminalInnerLocked::StandardStream(s) => s.write(buf),
#[cfg(feature = "test")]
TerminalInnerLocked::TestWriter(w) => w.write(buf),
}
self.locked.as_write().write(buf)
}

fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
self.locked.as_write().write_vectored(bufs)
}

fn flush(&mut self) -> io::Result<()> {
match &mut self.locked {
TerminalInnerLocked::StandardStream(s) => s.flush(),
#[cfg(feature = "test")]
TerminalInnerLocked::TestWriter(w) => w.flush(),
}
self.locked.as_write().flush()
}

fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
self.locked.as_write().write_all(buf)
}

fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> {
self.locked.as_write().write_fmt(args)
}
}

Expand Down
Loading