use std::cell::RefCell;
use fern::Dispatch;
use log::SetLoggerError;
thread_local! {
pub(crate) static LOGGER: RefCell<Option<Dispatch>> = RefCell::new(None);
}
pub(crate) fn set_logger(dispatch: Dispatch) {
LOGGER.with(|logger| {
*logger.borrow_mut() = Some(dispatch);
});
}
pub(crate) fn add_sink(dispatch: Dispatch) -> Result<(), LoggerError> {
match LOGGER.with(|logger| logger.borrow_mut().take()) {
None => Err(LoggerError::NoLogger),
Some(top_level_dispatch) => {
let top_level_dispatch = top_level_dispatch.chain(dispatch);
LOGGER.with(|logger| {
*logger.borrow_mut() = Some(top_level_dispatch)
});
Ok(())
}
}
}
pub(crate) fn apply_logger() -> Result<(), LoggerError> {
match LOGGER.with(|logger| logger.borrow_mut().take()) {
Some(logger) => Ok(logger.apply()?),
None => Err(LoggerError::NoLogger),
}
}
#[derive(Debug, thiserror::Error)]
pub(crate) enum LoggerError {
#[error("no logger initialized")]
NoLogger,
#[error(transparent)]
ApplyLoggerFailed(#[from] SetLoggerError),
}