use std::io::{self, Write};
pub(crate) fn report_leak(message: std::fmt::Arguments<'_>) {
#[cfg(test)]
if capture::push(&message) {
return;
}
let mut stderr = io::stderr().lock();
let _ = writeln!(stderr, "{message}");
}
#[cfg(test)]
pub(crate) mod capture {
use std::sync::{Mutex, MutexGuard};
static ACTIVE: Mutex<()> = Mutex::new(());
static CAPTURED: Mutex<Option<Vec<String>>> = Mutex::new(None);
pub(crate) struct Capture {
_serial: MutexGuard<'static, ()>,
}
pub(crate) fn start() -> Capture {
let serial = ACTIVE.lock().unwrap_or_else(|e| e.into_inner());
*CAPTURED.lock().unwrap() = Some(Vec::new());
Capture { _serial: serial }
}
impl Capture {
pub(crate) fn take(&mut self) -> Vec<String> {
CAPTURED.lock().unwrap().take().unwrap_or_default()
}
}
impl Drop for Capture {
fn drop(&mut self) {
let _ = CAPTURED.lock().map(|mut c| c.take());
}
}
pub(crate) fn push(message: &std::fmt::Arguments<'_>) -> bool {
let mut captured = CAPTURED.lock().unwrap();
match captured.as_mut() {
Some(messages) => {
messages.push(message.to_string());
true
}
None => false,
}
}
}