pure_ref/
lib.rs

1//! The purspose of this library is to provide a way to take a reference to a potentionally mutable variable.
2//! Potentially mutable meaning it could be mutable in a struct.
3//!
4//! ```
5//! use pure_ref::Pure;
6//!
7//! let pure = Pure::new(10);
8//! let borrowed = pure.borrowed();
9//! // or `let borrowed = *pure;`
10//! assert_eq!(*borrowed, 10);
11//! ````
12//!
13//!
14//!
15//!
16//!
17//!
18
19use std::marker::PhantomData;
20use std::ops::Deref;
21
22#[derive(Clone)]
23pub struct Pure<'a, T> {
24    data: T,
25    refs: Vec<*const T>,
26    _phantom: PhantomData<&'a T>,
27}
28
29unsafe impl<'a, T> Send for Pure<'a, T> {}
30unsafe impl<'a, T> Sync for Pure<'a, T> {}
31
32impl<'a, T> Pure<'a, T> {
33    pub fn new(data: T) -> Self {
34        Self {
35            data,
36            refs: Vec::new(),
37            _phantom: PhantomData,
38        }
39    }
40
41    pub fn borrow(&self) -> &'a T {
42        // Worst thing ever.
43        // Unchecked
44        #[allow(mutable_transmutes)]
45        let self_: &mut Self = unsafe { std::mem::transmute(self) };
46
47        let boxed = unsafe { Box::from_raw(&mut self_.data as *mut T) };
48        let boxed = Box::leak(boxed) as &T;
49
50        let refer = boxed as *const T;
51        self_.refs.push(refer);
52
53        boxed
54    }
55}
56
57/// Deref for Pure Struct
58impl<'a, T> Deref for Pure<'a, T> {
59    type Target = T;
60
61    fn deref(&self) -> &'a Self::Target {
62        self.borrow()
63    }
64}
65
66/// Drop the Pure Struct
67impl<'a, T> Drop for Pure<'a, T> {
68    fn drop(&mut self) {
69        for ref_ in self.refs.iter() {
70            drop(*ref_)
71        }
72    }
73}