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}