use std::cell::{Cell, UnsafeCell};
pub struct WithCell<T> {
borrowed: Cell<bool>,
data: UnsafeCell<T>,
}
impl<T> WithCell<T> {
pub const fn new(data: T) -> Self {
WithCell {
borrowed: Cell::new(false),
data: UnsafeCell::new(data),
}
}
pub fn with<F, O>(&self, mutator: F) -> O
where
F: FnOnce(&mut T) -> O,
O: 'static,
{
if self.borrowed.get() {
wasm_bindgen::throw_str("Cyclic state borrowing");
}
self.borrowed.set(true);
let result = mutator(unsafe { &mut *self.data.get() });
self.borrowed.set(false);
result
}
pub unsafe fn ref_unchecked(&self) -> &T {
debug_assert!(!self.borrowed.get());
&*self.data.get()
}
#[allow(clippy::mut_from_ref)]
pub unsafe fn mut_unchecked(&self) -> &mut T {
debug_assert!(!self.borrowed.get());
&mut *self.data.get()
}
}