use alloc::boxed::Box;
use core::mem::ManuallyDrop;
use crate::runtime::with_backend;
pub struct LazyCell<T: 'static> {
init: fn() -> T,
}
impl<T> LazyCell<T> {
#[doc(hidden)]
pub const fn new(init: fn() -> T) -> Self {
Self { init }
}
pub fn with<F, R>(&'static self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
let init = self.init;
let value: ManuallyDrop<T> =
match with_backend(|runtime| runtime.take_thread_local_box(self)) {
Some(value) => *value.downcast::<ManuallyDrop<T>>().expect("type mismatch"),
None => ManuallyDrop::new(init()),
};
let result = f(&value);
with_backend(|runtime| {
runtime.insert_thread_local_box(self, Box::new(value));
});
result
}
}
pub type JsThreadLocal<T> = LazyCell<T>;