use crate::level::Level;
use crate::record::LogRecord;
use parking_lot::RwLock;
use std::sync::Arc;
pub type LogCallback = Arc<dyn Fn(&LogRecord) -> Result<(), String> + Send + Sync>;
pub type ColorCallback = Arc<dyn Fn(Level, &str) -> String + Send + Sync>;
pub type ExceptionCallback = Arc<dyn Fn(&str, &str) + Send + Sync>;
#[derive(Clone)]
pub struct CallbackManager {
log_callbacks: Arc<RwLock<Vec<LogCallback>>>,
color_callbacks: Arc<RwLock<Vec<ColorCallback>>>,
exception_callbacks: Arc<RwLock<Vec<ExceptionCallback>>>,
}
impl CallbackManager {
pub fn new() -> Self {
Self {
log_callbacks: Arc::new(RwLock::new(Vec::new())),
color_callbacks: Arc::new(RwLock::new(Vec::new())),
exception_callbacks: Arc::new(RwLock::new(Vec::new())),
}
}
pub fn add_log_callback(&self, callback: LogCallback) {
self.log_callbacks.write().push(callback);
}
pub fn add_color_callback(&self, callback: ColorCallback) {
self.color_callbacks.write().push(callback);
}
pub fn add_exception_callback(&self, callback: ExceptionCallback) {
self.exception_callbacks.write().push(callback);
}
pub fn execute_log_callbacks(&self, record: &LogRecord) -> Vec<String> {
let callbacks = self.log_callbacks.read();
let mut errors = Vec::new();
for callback in callbacks.iter() {
if let Err(e) = callback(record) {
errors.push(e);
}
}
errors
}
pub fn execute_color_callbacks(&self, level: Level, message: &str) -> Option<String> {
let callbacks = self.color_callbacks.read();
callbacks.first().map(|callback| callback(level, message))
}
pub fn execute_exception_callbacks(&self, error: &str, backtrace: &str) {
let callbacks = self.exception_callbacks.read();
for callback in callbacks.iter() {
callback(error, backtrace);
}
}
pub fn clear_log_callbacks(&self) {
self.log_callbacks.write().clear();
}
pub fn clear_color_callbacks(&self) {
self.color_callbacks.write().clear();
}
pub fn clear_exception_callbacks(&self) {
self.exception_callbacks.write().clear();
}
pub fn clear_all(&self) {
self.clear_log_callbacks();
self.clear_color_callbacks();
self.clear_exception_callbacks();
}
}
impl Default for CallbackManager {
fn default() -> Self {
Self::new()
}
}