interior_mutability_pointer/
lib.rs

1#![feature(dispatch_from_dyn)]
2#![feature(unsize)]
3#![feature(coerce_unsized)]
4
5mod imp_impls;
6mod tests;
7
8use std::{cell::RefCell, rc::Rc};
9
10#[doc = include_str!("../readme.md")]
11pub struct Imp<T: ?Sized> {
12    v: Rc<RefCell<T>>,
13}
14
15#[allow(unused)]
16impl<T> Imp<T> {
17    /// Returns a pointer to the data
18    ///
19    /// # Arguments
20    ///
21    /// * `t` - The value to be pointed to.
22    ///
23    /// # Examples
24    ///
25    /// ```
26    /// use interior_mutability_pointer::Imp;
27    /// let mut p = unsafe { Imp::new(String::new())};
28    /// let p2 = p.clone();
29    /// p.push_str("yoo"); // Modifies the inner value of both p and p2.
30    /// ```
31    ///
32    /// # Safety
33    /// `DerefMut` implementation is unsound due to this library essentially working around the runtime safety provided
34    /// by using `RefCell`. See [Issue #2](https://github.com/samhamnam/interior_mutability_pointer/issues/2).
35    pub unsafe fn new(t: T) -> Self {
36        Self {
37            v: Rc::new(RefCell::new(t)),
38        }
39    }
40
41    /// Returns true if two pointers are equal
42    ///
43    /// # Arguments
44    /// * `this` - A pointer to compare
45    /// * `other` - The other pointer to compare to
46    ///
47    /// # Examples
48    /// ```
49    /// use interior_mutability_pointer::Imp;
50    /// let p1 = unsafe { Imp::new(String::new()) };
51    /// let p2 = p1.clone();
52    /// let p3 = unsafe { Imp::new(String::new()) };
53    /// println!("{}", Imp::ptr_eq(&p1, &p2)); // Prints true
54    /// println!("{}", Imp::ptr_eq(&p1, &p3)); // Prints false
55    /// ```
56    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
57        Rc::ptr_eq(&this.v, &other.v)
58    }
59}
60
61/*
62    Implements cloning the pointer.
63*/
64mod clone_impl {
65    use super::Imp;
66    use std::clone::Clone;
67
68    impl<T: ?Sized> Clone for Imp<T> {
69        fn clone(&self) -> Self {
70            Self { v: self.v.clone() }
71        }
72    }
73}
74
75/*
76    Allows access to the inner methods from T.
77*/
78mod deref_impl {
79    use std::{
80        marker::Unsize,
81        ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn},
82    };
83
84    use super::Imp;
85
86    impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Imp<U>> for Imp<T> {}
87    impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Imp<U>> for Imp<T> {}
88
89    impl<T: ?Sized> Deref for Imp<T> {
90        type Target = T;
91
92        fn deref(&self) -> &Self::Target {
93            unsafe { &*self.v.as_ptr() }
94        }
95    }
96
97    impl<T: ?Sized> DerefMut for Imp<T> {
98        fn deref_mut(&mut self) -> &mut Self::Target {
99            unsafe { &mut *self.v.as_ptr() }
100        }
101    }
102}