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}