use crate::preload::*;
use e_utils::once_cell::sync::Lazy;
use parking_lot::RwLock;
use std::path::{Path, PathBuf};
pub(crate) static BAD_MODULES: Lazy<BadModules> = Lazy::new(BadModules::default);
type Subscriber = Box<dyn Fn(PathBuf) + Send + Sync + 'static>;
#[derive(Default)]
pub(crate) struct BadModules {
subscribers: RwLock<Vec<Subscriber>>,
}
impl BadModules {
#[allow(unused)]
pub(crate) fn add_subscriber<F>(&self, subscriber: F)
where
F: Fn(PathBuf) + Send + Sync + 'static,
{
self.subscribers.write().push(Box::new(subscriber));
info2!("Registered callback!");
}
fn push(&self, path: PathBuf) {
self
.subscribers
.read()
.iter()
.for_each(|notify| notify(path.clone()));
}
}
#[inline]
pub fn log_file_on_panic<'a, T, F>(path: &'a Path, func: F) -> T
where
F: Fn(&'a Path) -> T,
{
struct LogOnUnwind<'a> {
suspect_file: &'a Path,
}
impl<'a> LogOnUnwind<'a> {
fn new(suspect_file: &'a Path) -> Self {
Self { suspect_file }
}
fn execute<T, F>(self, func: F) -> T
where
F: Fn(&'a Path) -> T,
{
func(self.suspect_file)
}
}
impl<'a> Drop for LogOnUnwind<'a> {
fn drop(&mut self) {
#[cold]
fn add(path: &Path) {
BAD_MODULES.push(path.to_owned());
}
if std::thread::panicking() {
add(self.suspect_file);
}
}
}
LogOnUnwind::new(path).execute(func)
}