diff --git a/src/process/terminalsource.rs b/src/process/terminalsource.rs index 46b510c661..b0331b4b01 100644 --- a/src/process/terminalsource.rs +++ b/src/process/terminalsource.rs @@ -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, @@ -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 @@ -202,37 +222,50 @@ pub enum Attr { impl io::Write for ColorableTerminal { fn write(&mut self, buf: &[u8]) -> std::result::Result { - 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 { + 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 { - 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 { + 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) } }