Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(filesource): replace repetitive #[cfg()] usages with cfg_if!{} #3832

Closed
wants to merge 1 commit into from
Closed
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
194 changes: 93 additions & 101 deletions src/currentprocess/filesource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{
sync::{Arc, Mutex, MutexGuard},
};

use cfg_if::cfg_if;
use enum_dispatch::enum_dispatch;

use super::terminalsource::{ColorableTerminal, StreamSelector};
Expand Down Expand Up @@ -47,53 +48,49 @@ impl StdinSource for super::OSProcess {

// ----------------------- test support for stdin ------------------

#[cfg(feature = "test")]
struct TestStdinLock<'a> {
inner: MutexGuard<'a, Cursor<String>>,
}
cfg_if! {
if #[cfg(feature = "test")] {
struct TestStdinLock<'a> {
inner: MutexGuard<'a, Cursor<String>>,
}

#[cfg(feature = "test")]
impl StdinLock for TestStdinLock<'_> {}
impl StdinLock for TestStdinLock<'_> {}

#[cfg(feature = "test")]
impl Read for TestStdinLock<'_> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl Read for TestStdinLock<'_> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}

#[cfg(feature = "test")]
impl BufRead for TestStdinLock<'_> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
self.inner.fill_buf()
}
fn consume(&mut self, n: usize) {
self.inner.consume(n)
}
}
impl BufRead for TestStdinLock<'_> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
self.inner.fill_buf()
}
fn consume(&mut self, n: usize) {
self.inner.consume(n)
}
}

#[cfg(feature = "test")]
pub(crate) type TestStdinInner = Arc<Mutex<Cursor<String>>>;
pub(crate) type TestStdinInner = Arc<Mutex<Cursor<String>>>;

#[cfg(feature = "test")]
struct TestStdin(TestStdinInner);
struct TestStdin(TestStdinInner);

#[cfg(feature = "test")]
impl Stdin for TestStdin {
fn lock(&self) -> Box<dyn StdinLock + '_> {
Box::new(TestStdinLock {
inner: self.0.lock().unwrap_or_else(|e| e.into_inner()),
})
}
fn read_line(&self, buf: &mut String) -> Result<usize> {
self.lock().read_line(buf)
}
}
impl Stdin for TestStdin {
fn lock(&self) -> Box<dyn StdinLock + '_> {
Box::new(TestStdinLock {
inner: self.0.lock().unwrap_or_else(|e| e.into_inner()),
})
}
fn read_line(&self, buf: &mut String) -> Result<usize> {
self.lock().read_line(buf)
}
}

#[cfg(feature = "test")]
impl StdinSource for super::TestProcess {
fn stdin(&self) -> Box<dyn Stdin> {
Box::new(TestStdin(self.stdin.clone()))
impl StdinSource for super::TestProcess {
fn stdin(&self) -> Box<dyn Stdin> {
Box::new(TestStdin(self.stdin.clone()))
}
}
}
}

Expand Down Expand Up @@ -189,79 +186,74 @@ impl StderrSource for super::OSProcess {

// ----------------------- test support for writers ------------------

#[cfg(feature = "test")]
pub(super) struct TestWriterLock<'a> {
inner: MutexGuard<'a, Vec<u8>>,
}
cfg_if! {
if #[cfg(feature = "test")] {
pub(super) struct TestWriterLock<'a> {
inner: MutexGuard<'a, Vec<u8>>,
}

#[cfg(feature = "test")]
impl WriterLock for TestWriterLock<'_> {}
impl WriterLock for TestWriterLock<'_> {}

#[cfg(feature = "test")]
impl Write for TestWriterLock<'_> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.inner.write(buf)
}
impl Write for TestWriterLock<'_> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.inner.write(buf)
}

fn flush(&mut self) -> Result<()> {
Ok(())
}
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}

#[cfg(feature = "test")]
pub(super) type TestWriterInner = Arc<Mutex<Vec<u8>>>;
/// A thread-safe test file handle that pretends to be e.g. stdout.
#[derive(Clone, Default)]
#[cfg(feature = "test")]
pub(super) struct TestWriter(TestWriterInner);
pub(super) type TestWriterInner = Arc<Mutex<Vec<u8>>>;

#[cfg(feature = "test")]
impl TestWriter {
pub(super) fn lock(&self) -> TestWriterLock<'_> {
// The stream can be locked even if a test thread panicked: its state
// will be ok
TestWriterLock {
inner: self.0.lock().unwrap_or_else(|e| e.into_inner()),
/// A thread-safe test file handle that pretends to be e.g. stdout.
#[derive(Clone, Default)]
pub(super) struct TestWriter(TestWriterInner);

impl TestWriter {
pub(super) fn lock(&self) -> TestWriterLock<'_> {
// The stream can be locked even if a test thread panicked: its state
// will be ok
TestWriterLock {
inner: self.0.lock().unwrap_or_else(|e| e.into_inner()),
}
}
}
}
}

#[cfg(feature = "test")]
impl Writer for TestWriter {
fn is_a_tty(&self) -> bool {
false
}
impl Writer for TestWriter {
fn is_a_tty(&self) -> bool {
false
}

fn lock(&self) -> Box<dyn WriterLock + '_> {
Box::new(self.lock())
}
fn lock(&self) -> Box<dyn WriterLock + '_> {
Box::new(self.lock())
}

fn terminal(&self) -> ColorableTerminal {
ColorableTerminal::new(StreamSelector::TestWriter(self.clone()))
}
}
fn terminal(&self) -> ColorableTerminal {
ColorableTerminal::new(StreamSelector::TestWriter(self.clone()))
}
}

#[cfg(feature = "test")]
impl Write for TestWriter {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.lock().write(buf)
}
impl Write for TestWriter {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.lock().write(buf)
}

fn flush(&mut self) -> Result<()> {
Ok(())
}
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}

#[cfg(feature = "test")]
impl StdoutSource for super::TestProcess {
fn stdout(&self) -> Box<dyn Writer> {
Box::new(TestWriter(self.stdout.clone()))
}
}
impl StdoutSource for super::TestProcess {
fn stdout(&self) -> Box<dyn Writer> {
Box::new(TestWriter(self.stdout.clone()))
}
}

#[cfg(feature = "test")]
impl StderrSource for super::TestProcess {
fn stderr(&self) -> Box<dyn Writer> {
Box::new(TestWriter(self.stderr.clone()))
impl StderrSource for super::TestProcess {
fn stderr(&self) -> Box<dyn Writer> {
Box::new(TestWriter(self.stderr.clone()))
}
}
}
}
Loading