blob: de1aea11ade9b8e3877489db55984057e7657aa3 [file]
use std::fmt;
use std::panic::RefUnwindSafe;
use std::sync::Mutex;
pub trait ConsoleOut: fmt::Debug + RefUnwindSafe {
fn write_fmt(&self, args: fmt::Arguments<'_>);
}
#[derive(Debug)]
pub(crate) struct Stdout;
impl ConsoleOut for Stdout {
fn write_fmt(&self, args: fmt::Arguments<'_>) {
print!("{args}");
}
}
#[derive(Debug)]
pub(crate) struct Stderr;
impl ConsoleOut for Stderr {
fn write_fmt(&self, args: fmt::Arguments<'_>) {
eprint!("{args}");
}
}
pub(crate) struct CaptureBuf {
inner: Mutex<String>,
}
impl CaptureBuf {
pub(crate) fn new() -> Self {
Self { inner: Mutex::new(String::new()) }
}
pub(crate) fn into_inner(self) -> String {
self.inner.into_inner().unwrap_or_else(|e| e.into_inner())
}
}
impl fmt::Debug for CaptureBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CaptureBuf").finish_non_exhaustive()
}
}
impl ConsoleOut for CaptureBuf {
fn write_fmt(&self, args: fmt::Arguments<'_>) {
let mut s = self.inner.lock().unwrap_or_else(|e| e.into_inner());
<String as fmt::Write>::write_fmt(&mut s, args).unwrap();
}
}