gemstone 0.3.0

collection of utilities
Documentation
use std::{
    cell::UnsafeCell,
    mem::transmute,
    ops::{Deref, DerefMut},
    rc::{Rc, Weak},
};

/// Opt-out of runtime borrow checking of RefCell by using UnsafeCell
///
/// # Safety
///
/// Up to the user to make sure the usage of the shared object is safe
#[derive(Debug, Default)]
pub struct Shared<T>(Rc<UnsafeCell<T>>);

impl<T> Shared<T> {
    pub fn new(t: T) -> Shared<T> {
        Shared(Rc::new(UnsafeCell::new(t)))
    }

	/// Allows creating a cyclic Shared<T>
	/// 
	/// See [`std::rc::Rc::new_cyclic`] for more info.
	///
    /// NOTE: 
    /// Is it defined behavior transmute T -> UnsafeCell<T>
    ///
    /// The standard library can... but can we in user space?
    pub fn new_cyclic<F>(data_fn: F) -> Self
    where
        F: FnOnce(&Weak<T>) -> T,
    {
        let x = unsafe { transmute(Rc::new_cyclic(|m| data_fn(m))) };
        Self(x)
    }

    /// # Safety
    ///
    /// Up to the user to make sure the usage of the shared object is safe
    #[allow(clippy::mut_from_ref)]
    pub unsafe fn inner_unsafe(&self) -> &mut T {
        &mut (*self.0.get())
    }

    pub fn clone_inner(&self) -> T
    where
        T: Clone,
    {
        self.deref().clone()
    }
}

impl<T> Clone for Shared<T> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

impl<T> Deref for Shared<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        unsafe { &(*self.0.get()) }
    }
}

impl<T> DerefMut for Shared<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut (*self.0.get()) }
    }
}