use std::sync::{Mutex, OnceLock};
#[derive(Default)]
pub struct Global<T> {
inner: OnceLock<Mutex<T>>,
}
impl<T> Global<T> {
pub const fn new() -> Self {
Self { inner: OnceLock::new() }
}
pub fn set(&self, value: T) {
match self.inner.get() {
Some(inner) => {
*inner.lock().unwrap() = value;
},
None => {
let Ok(_) = self.inner.set(Mutex::new(value)) else {
unreachable!(
"get returned `None`, so the set will succeed"
);
};
},
}
}
pub fn with<F, R>(&self, fun: F) -> R
where
F: FnOnce(Option<&T>) -> R,
{
let Some(lock) = self.inner.get() else { return fun(None) };
let value = &*lock.lock().unwrap();
fun(Some(value))
}
}