compiletest/
output_capture.rs

1use std::fmt;
2use std::panic::RefUnwindSafe;
3use std::sync::Mutex;
4
5pub trait ConsoleOut: fmt::Debug + RefUnwindSafe {
6    fn write_fmt(&self, args: fmt::Arguments<'_>);
7}
8
9#[derive(Debug)]
10pub(crate) struct Stdout;
11
12impl ConsoleOut for Stdout {
13    fn write_fmt(&self, args: fmt::Arguments<'_>) {
14        print!("{args}");
15    }
16}
17
18#[derive(Debug)]
19pub(crate) struct Stderr;
20
21impl ConsoleOut for Stderr {
22    fn write_fmt(&self, args: fmt::Arguments<'_>) {
23        eprint!("{args}");
24    }
25}
26
27pub(crate) struct CaptureBuf {
28    inner: Mutex<String>,
29}
30
31impl CaptureBuf {
32    pub(crate) fn new() -> Self {
33        Self { inner: Mutex::new(String::new()) }
34    }
35
36    pub(crate) fn into_inner(self) -> String {
37        self.inner.into_inner().unwrap_or_else(|e| e.into_inner())
38    }
39}
40
41impl fmt::Debug for CaptureBuf {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        f.debug_struct("CaptureBuf").finish_non_exhaustive()
44    }
45}
46
47impl ConsoleOut for CaptureBuf {
48    fn write_fmt(&self, args: fmt::Arguments<'_>) {
49        let mut s = self.inner.lock().unwrap_or_else(|e| e.into_inner());
50        <String as fmt::Write>::write_fmt(&mut s, args).unwrap();
51    }
52}