use std::cell::RefCell;
use std::sync::Once;
thread_local! {
static CAPTURE: RefCell<Option<Vec<String>>> = const { RefCell::new(None) };
}
struct AnydocLogBridge;
impl log::Log for AnydocLogBridge {
fn enabled(&self, metadata: &log::Metadata) -> bool {
metadata.level() <= log::Level::Warn
}
fn log(&self, record: &log::Record) {
if record.level() > log::Level::Warn || !record.target().starts_with("anydoc") {
return;
}
CAPTURE.with(|capture| {
if let Some(sink) = capture.borrow_mut().as_mut() {
sink.push(record.args().to_string());
}
});
}
fn flush(&self) {}
}
static BRIDGE: AnydocLogBridge = AnydocLogBridge;
static INSTALL: Once = Once::new();
fn install_bridge() {
INSTALL.call_once(|| {
if log::set_logger(&BRIDGE).is_ok() {
log::set_max_level(log::LevelFilter::Warn);
}
});
}
pub fn capture_anydoc<T>(work: impl FnOnce() -> T) -> (T, Vec<String>) {
install_bridge();
CAPTURE.with(|capture| *capture.borrow_mut() = Some(Vec::new()));
let result = work();
let captured = CAPTURE
.with(|capture| capture.borrow_mut().take())
.unwrap_or_default();
(result, captured)
}