me_cell/
lib.rs

1use std::ops::{Deref, DerefMut};
2use std::rc::Rc;
3use std::fmt;
4use std::cell::UnsafeCell;
5
6pub struct MeBorrowError {
7    msg: &'static str
8}
9impl fmt::Debug for MeBorrowError {
10    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11        write!(f, "{}", self.msg)
12    }
13}
14impl fmt::Display for MeBorrowError {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        write!(f, "{}", self.msg)
17    }
18}
19impl std::error::Error for MeBorrowError {}
20
21struct Ctx {
22    is_mut: UnsafeCell<bool>,
23    count: UnsafeCell<usize>,
24}
25
26pub struct MeCell<T> {
27    ctx: Rc<Ctx>,
28    content: UnsafeCell<T>,
29}
30
31impl<T> MeCell<T> {
32    pub fn new_group(content: T) -> Self {
33        Self {
34            ctx: Rc::new(Ctx {
35                is_mut: UnsafeCell::new(false),
36                count: UnsafeCell::new(0),
37            }),
38            content: UnsafeCell::new(content),
39        }
40    }
41    pub fn borrow(&self) -> MeRef<T> {
42        unsafe {
43            if *self.ctx.is_mut.get() { panic!("MeCell has been mutably borrowed") };
44            *self.ctx.count.get() += 1;
45        }
46        MeRef { handle: MeRefHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &*self.content.get() } }
47    }
48    pub fn try_borrow(&self) -> Result<MeRef<T>, MeBorrowError> {
49        unsafe {
50            if *self.ctx.is_mut.get() { return Err(MeBorrowError { msg: "MeCell has been mutably borrowed" }) };
51            *self.ctx.count.get() += 1;
52        }
53        Ok(MeRef { handle: MeRefHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &*self.content.get() } })
54    }
55    pub fn borrow_mut(&self) -> MeRefMut<T> {
56        unsafe {
57            if *self.ctx.is_mut.get() || *self.ctx.count.get() > 0 { panic!("MeCell has been borrowed") };
58            *self.ctx.is_mut.get() = true;
59        }
60        MeRefMut { handle: MeRefMutHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &mut *self.content.get() } }
61    }
62    pub fn try_borrow_mut(&self) -> Result<MeRefMut<T>, MeBorrowError> {
63        unsafe {
64            if *self.ctx.is_mut.get() || *self.ctx.count.get() > 0 { return Err(MeBorrowError { msg: "MeCell has been borrowed" }) };
65            *self.ctx.is_mut.get() = true;
66        }
67        Ok(MeRefMut { handle: MeRefMutHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &mut *self.content.get() } })
68    }
69    pub fn borrow_with<'a: 'b, 'b, U>(&'b self, source: &'b MeRef<'a, U>) -> MeRef<'b, T> {
70        source.another(self)
71    }
72    pub fn borrow_mut_with<'a: 'b, 'b, U>(&'b self, source: &'b mut MeRefMut<'a, U>) -> MeRefMut<'b, T> {
73        source.another_mut(self)
74    }
75    pub unsafe fn borrow_mut_unsafe_with<'a: 'b, 'b, 'c, U>(&'c self, source: &'b mut MeRefMut<'a, U>) -> MeRefMut<'c, T> {
76        source.another_mut_unsafe(self)
77    }
78    pub fn borrow_with_handle<'a: 'b, 'b>(&'b self, source: &'b MeRefHandle<'a>) -> MeRef<'b, T> {
79        source.another(self)
80    }
81    pub fn borrow_mut_with_handle<'a: 'b, 'b>(&'b self, source: &'b mut MeRefMutHandle<'a>) -> MeRefMut<'b, T> {
82        source.another_mut(self)
83    }
84    pub unsafe fn borrow_mut_unsafe_with_handle<'a: 'b, 'b, 'c>(&'c self, source: &'b mut MeRefMutHandle<'a>) -> MeRefMut<'c, T> {
85        source.another_mut_unsafe(self)
86    }
87}
88
89pub struct MeRefHandle<'a> {
90    is_source: bool,
91    ctx: &'a Rc<Ctx>,
92}
93impl<'a> MeRefHandle<'a> {
94    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
95        if !Rc::ptr_eq(&another.ctx, self.ctx) {
96            panic!("A MeCell can only be borrowed with another MeCell in the same group");
97        }
98        MeRef { handle: MeRefHandle { is_source: false, ctx: self.ctx }, content: unsafe { &*another.content.get() } }
99    }
100    fn duplicate<'b>(&'b self) -> MeRefHandle<'b> where 'a: 'b {
101        MeRefHandle { is_source: false, ctx: self.ctx }
102    }
103}
104impl<'a> Drop for MeRefHandle<'a> {
105    fn drop(&mut self) {
106        if !self.is_source { return };
107        let c = self.ctx.count.get();
108        unsafe {
109            *c -= 1;
110        }
111    }
112}
113
114pub struct MeRefMutHandle<'a> {
115    is_source: bool,
116    ctx: &'a Rc<Ctx>
117}
118impl<'a> MeRefMutHandle<'a> {
119    pub fn entrance<U>(&mut self, content: U) -> MeCell<U> {
120        MeCell {
121            ctx: self.ctx.clone(),
122            content: UnsafeCell::new(content),
123        }
124    }
125    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
126        if !Rc::ptr_eq(&another.ctx, self.ctx) {
127            panic!("A MeCell can only be borrowed with another MeCell in the same group");
128        }
129        MeRef { handle: MeRefHandle { is_source: false, ctx: self.ctx }, content: unsafe { &*another.content.get() } }
130    }
131    pub fn another_mut<'b, U>(&'b mut self, another: &'b MeCell<U>) -> MeRefMut<'b, U> where 'a: 'b {
132        if !Rc::ptr_eq(&another.ctx, self.ctx) {
133            panic!("A MeCell can only be borrowed with another MeCell in the same group");
134        }
135        MeRefMut { handle: MeRefMutHandle { is_source: false, ctx: self.ctx }, content: unsafe { &mut *another.content.get() } }
136    }
137    fn duplicate<'b>(&'b self) -> MeRefMutHandle<'b> where 'a: 'b {
138        MeRefMutHandle { is_source: false, ctx: self.ctx }
139    }
140    pub unsafe fn another_mut_unsafe<'b, 'c, U>(&'b mut self, another: &'c MeCell<U>) -> MeRefMut<'c, U> where 'a: 'b {
141        if !Rc::ptr_eq(&another.ctx, self.ctx) {
142            panic!("A MeCell can only be borrowed with another MeCell in the same group");
143        }
144        MeRefMut { handle: MeRefMutHandle { is_source: false, ctx: &another.ctx }, content: &mut *another.content.get() }
145    }
146}
147impl<'a> Drop for MeRefMutHandle<'a> {
148    fn drop(&mut self) {
149        if !self.is_source { return };
150        let is_mut = self.ctx.is_mut.get();
151        unsafe {
152            *is_mut = false;
153        }
154    }
155}
156
157pub struct MeRef<'a, T> {
158    handle: MeRefHandle<'a>,
159    content: &'a T,
160}
161impl<'a, T> MeRef<'a, T> {
162    pub fn handle(&self) -> &MeRefHandle<'a> {
163        &self.handle
164    }
165    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
166        self.handle.another(another)
167    }
168    pub fn duplicate<'b>(&'b self) -> MeRef<'b, T> where 'a: 'b {
169        MeRef {
170            handle: self.handle.duplicate(),
171            content: self.content,
172        }
173    }
174    pub fn map<'b, U, F>(self, f: F) -> MeRef<'b, U> where 'a: 'b, F: FnOnce(&T) -> &U {
175        MeRef { handle: self.handle, content: f(self.content) }
176    }
177}
178impl<'a, T> Deref for MeRef<'a, T> {
179    type Target = T;
180    fn deref(&self) -> &T {
181        self.content
182    }
183}
184impl<'a, T: fmt::Debug> fmt::Debug for MeRef<'a, T> {
185    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186        write!(f, "{:?}", self.content)
187    }
188}
189impl<'a, T: fmt::Display> fmt::Display for MeRef<'a, T> {
190    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191        write!(f, "{}", self.content)
192    }
193}
194
195pub struct MeRefMut<'a, T> {
196    handle: MeRefMutHandle<'a>,
197    content: &'a mut T,
198}
199impl<'a, T> MeRefMut<'a, T> {
200    pub fn handle_mut(&mut self) -> &mut MeRefMutHandle<'a> {
201        &mut self.handle
202    }
203    pub fn entrance<U>(&mut self, content: U) -> MeCell<U> {
204        self.handle.entrance(content)
205    }
206    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
207        self.handle.another(another)
208    }
209    pub fn another_mut<'b, U>(&'b mut self, another: &'b MeCell<U>) -> MeRefMut<'b, U> where 'a: 'b {
210        self.handle.another_mut(another)
211    }
212    pub unsafe fn another_mut_unsafe<'b, 'c, U>(&'b mut self, another: &'c MeCell<U>) -> MeRefMut<'c, U> where 'a: 'b {
213        self.handle.another_mut_unsafe(another)
214    }
215    pub fn duplicate<'b>(&'b mut self) -> MeRefMut<'b, T> where 'a: 'b {
216        MeRefMut {
217            handle: self.handle.duplicate(),
218            content: self.content,
219        }
220    }
221    pub fn to_ref<'b>(&'b self) -> MeRef<'b, T> where 'a: 'b {
222        MeRef { handle: MeRefHandle { is_source: false, ctx: self.handle.ctx }, content: &*self.content }
223    }
224    pub fn map<'b, U, F>(self, f: F) -> MeRefMut<'b, U> where 'a: 'b, F: FnOnce(&mut T) -> &mut U {
225        MeRefMut { handle: self.handle, content: f(self.content) }
226    }
227}
228impl<'a, T> Deref for MeRefMut<'a, T> {
229    type Target = T;
230    fn deref(&self) -> &T {
231        self.content
232    }
233}
234impl<'a, T> DerefMut for MeRefMut<'a, T> {
235    fn deref_mut(&mut self) -> &mut T {
236        self.content
237    }
238}
239impl<'a, T: fmt::Debug> fmt::Debug for MeRefMut<'a, T> {
240    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241        write!(f, "{:?}", self.content)
242    }
243}
244impl<'a, T: fmt::Display> fmt::Display for MeRefMut<'a, T> {
245    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246        write!(f, "{}", self.content)
247    }
248}