pure_ref 0.1.3

A library for making immutable references only
Documentation
//! The purspose of this library is to provide a way to take a reference to a potentionally mutable variable.
//! Potentially mutable meaning it could be mutable in a struct.
//!
//! ```
//! use pure_ref::Pure;
//!
//! let pure = Pure::new(10);
//! let borrowed = pure.borrowed();
//! // or `let borrowed = *pure;`
//! assert_eq!(*borrowed, 10);
//! ````
//!
//!
//!
//!
//!
//!

use std::marker::PhantomData;
use std::ops::Deref;

#[derive(Clone)]
pub struct Pure<'a, T> {
    data: T,
    refs: Vec<*const T>,
    _phantom: PhantomData<&'a T>,
}

unsafe impl<'a, T> Send for Pure<'a, T> {}
unsafe impl<'a, T> Sync for Pure<'a, T> {}

impl<'a, T> Pure<'a, T> {
    pub fn new(data: T) -> Self {
        Self {
            data,
            refs: Vec::new(),
            _phantom: PhantomData,
        }
    }

    pub fn borrow(&self) -> &'a T {
        // Worst thing ever.
        // Unchecked
        #[allow(mutable_transmutes)]
        let self_: &mut Self = unsafe { std::mem::transmute(self) };

        let boxed = unsafe { Box::from_raw(&mut self_.data as *mut T) };
        let boxed = Box::leak(boxed) as &T;

        let refer = boxed as *const T;
        self_.refs.push(refer);

        boxed
    }
}

/// Deref for Pure Struct
impl<'a, T> Deref for Pure<'a, T> {
    type Target = T;

    fn deref(&self) -> &'a Self::Target {
        self.borrow()
    }
}

/// Drop the Pure Struct
impl<'a, T> Drop for Pure<'a, T> {
    fn drop(&mut self) {
        for ref_ in self.refs.iter() {
            drop(*ref_)
        }
    }
}