global_placeholders 0.1.0

Simple magic placeholders
Documentation
use std::{
    cell::{self, RefCell, UnsafeCell},
    error::Error,
    fmt,
    mem::{ManuallyDrop, MaybeUninit},
    ops::{Deref, DerefMut},
    sync::Arc,
};

use parking_lot::{Once, ReentrantMutex, ReentrantMutexGuard};

#[derive(Debug)]
pub struct BorrowFail;

impl fmt::Display for BorrowFail {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "failed to borrow global value twice in same thread") }
}

impl Error for BorrowFail {}

type InnerPointer<T> = Arc<ReentrantMutex<RefCell<T>>>;

pub struct Global<T>(Immutable<InnerPointer<T>>);

unsafe impl<T: Send> Sync for Global<T> {}
unsafe impl<T: Send> Send for Global<T> {}

impl<T> Global<T> {
    pub const fn new() -> Self { Self(Immutable::new()) }
}

impl<T: Default + 'static> Global<T> {
    pub fn with<F, R>(&self, f: F) -> R
    where
        F: FnOnce(&T) -> R,
    {
        f(&*self.lock().expect("Couldn't immutably access global variable"))
    }

    pub fn with_mut<F, R>(&self, f: F) -> R
    where
        F: FnOnce(&mut T) -> R,
    {
        f(&mut *self.lock_mut().expect("Couldn't mutably access global variable"))
    }

    pub fn lock(&self) -> Result<GlobalGuard<T>, BorrowFail> {
        let mutex: Arc<_> = Arc::clone(&*self.0);
        let mutex_ptr = &*mutex as *const ReentrantMutex<RefCell<T>>;

        let mutex_guard = unsafe { (*mutex_ptr).lock() };
        let mutex_guard_ptr = &*mutex_guard as *const RefCell<T>;

        let ref_cell_guard = unsafe { (*mutex_guard_ptr).try_borrow().map_err(|_| BorrowFail)? };

        Ok(GlobalGuard {
            mutex: ManuallyDrop::new(mutex),
            mutex_guard: ManuallyDrop::new(mutex_guard),
            ref_cell_guard: ManuallyDrop::new(ref_cell_guard),
        })
    }

    pub fn lock_mut(&self) -> Result<GlobalGuardMut<T>, BorrowFail> {
        let mutex: Arc<_> = Arc::clone(&*self.0);
        let mutex_ptr = &*mutex as *const ReentrantMutex<RefCell<T>>;

        let mutex_guard = unsafe { (*mutex_ptr).lock() };
        let mutex_guard_ptr = &*mutex_guard as *const RefCell<T>;

        let ref_cell_guard = unsafe { (*mutex_guard_ptr).try_borrow_mut().map_err(|_| BorrowFail)? };

        Ok(GlobalGuardMut {
            mutex: ManuallyDrop::new(mutex),
            mutex_guard: ManuallyDrop::new(mutex_guard),
            ref_cell_guard: ManuallyDrop::new(ref_cell_guard),
        })
    }

    pub fn force_init(&self) { self.0.ensure_exists(); }
}

pub struct GlobalGuardMut<T: 'static> {
    mutex: ManuallyDrop<Arc<ReentrantMutex<RefCell<T>>>>,
    mutex_guard: ManuallyDrop<ReentrantMutexGuard<'static, RefCell<T>>>,
    ref_cell_guard: ManuallyDrop<cell::RefMut<'static, T>>,
}

impl<T: 'static> Drop for GlobalGuardMut<T> {
    fn drop(&mut self) {
        unsafe {
            ManuallyDrop::drop(&mut self.ref_cell_guard);
            ManuallyDrop::drop(&mut self.mutex_guard);
            ManuallyDrop::drop(&mut self.mutex);
        }
    }
}

impl<T: 'static> Deref for GlobalGuardMut<T> {
    type Target = T;

    fn deref(&self) -> &T { &*self.ref_cell_guard }
}

impl<T: 'static> DerefMut for GlobalGuardMut<T> {
    fn deref_mut(&mut self) -> &mut T { &mut *self.ref_cell_guard }
}

pub struct GlobalGuard<T: 'static> {
    mutex: ManuallyDrop<Arc<ReentrantMutex<RefCell<T>>>>,
    mutex_guard: ManuallyDrop<ReentrantMutexGuard<'static, RefCell<T>>>,
    ref_cell_guard: ManuallyDrop<cell::Ref<'static, T>>,
}

impl<T: 'static> Drop for GlobalGuard<T> {
    fn drop(&mut self) {
        unsafe {
            ManuallyDrop::drop(&mut self.ref_cell_guard);
            ManuallyDrop::drop(&mut self.mutex_guard);
            ManuallyDrop::drop(&mut self.mutex);
        }
    }
}

impl<T: 'static> Deref for GlobalGuard<T> {
    type Target = T;

    fn deref(&self) -> &T { &*self.ref_cell_guard }
}

pub struct Immutable<T> {
    once: Once,
    inner: UnsafeCell<MaybeUninit<T>>,
}

impl<T> Drop for Immutable<T> {
    fn drop(&mut self) {
        if let parking_lot::OnceState::Done = self.once.state() {
            unsafe {
                std::ptr::drop_in_place((*self.inner.get()).as_mut_ptr());
            }
        }
    }
}

unsafe impl<T: Send> Send for Immutable<T> {}
unsafe impl<T: Sync> Sync for Immutable<T> {}

impl<T: Default> Immutable<T> {
    fn ensure_exists(&self) {
        self.once.call_once(|| unsafe {
            *self.inner.get() = MaybeUninit::new(T::default());
        });
    }

    pub fn force_init(&self) { self.ensure_exists(); }
}

impl<T> Immutable<T> {
    pub const fn new() -> Self {
        Self {
            once: Once::new(),
            inner: UnsafeCell::new(MaybeUninit::uninit()),
        }
    }
}

impl<T: Default> Deref for Immutable<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        self.ensure_exists();
        unsafe { &*(*self.inner.get()).as_ptr() }
    }
}