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}