use crate::task::Task;
use std::cell::RefCell;
use std::rc::Rc;
use std::thread_local;
pub struct TasksToAdd(Rc<RefCell<Vec<Task>>>);
impl TasksToAdd {
pub fn new() -> Self {
Self(Rc::new(RefCell::new(Vec::new())))
}
pub fn add(&self, task: Task) {
self.0.borrow_mut().push(task);
}
pub fn access_mut<R>(&self, f: impl FnOnce(&mut Vec<Task>) -> R) -> R {
f(&mut self.0.borrow_mut())
}
fn clone(&self) -> Self {
Self(Rc::clone(&self.0))
}
}
thread_local! {
#[cfg(not(test))]
static TASKS_TO_ADD_REF: RefCell<Option<TasksToAdd>> = RefCell::new(None);
#[cfg(test)]
static TASKS_TO_ADD_REF: RefCell<Option<(TasksToAdd, &'static str)>> = RefCell::new(None);
}
pub fn set_thread_local(tasks_to_add: &TasksToAdd, #[cfg(test)] name: &'static str) {
TASKS_TO_ADD_REF.with(|tasks_to_add_ref| {
#[cfg(not(test))]
tasks_to_add_ref.replace(Some(tasks_to_add.clone()));
#[cfg(test)]
tasks_to_add_ref.replace(Some((tasks_to_add.clone(), name)));
});
}
pub fn unset_thread_local() {
TASKS_TO_ADD_REF.with(|tasks_to_add_ref| {
tasks_to_add_ref.replace(None);
});
}
pub fn access_thread_local<R>(
#[cfg(not(test))] f: impl FnOnce(Option<&TasksToAdd>) -> R,
#[cfg(test)] f: impl FnOnce(Option<&(TasksToAdd, &'static str)>) -> R,
) -> R {
TASKS_TO_ADD_REF.with(|tasks_to_add_ref| f(tasks_to_add_ref.borrow().as_ref()))
}