1use std::fmt::{Debug, Display, Formatter};
4use std::marker::PhantomData;
5use std::ops::{Deref, DerefMut};
6use std::{fmt, mem};
7
8use crate::block::Block;
9use crate::id::Id;
10
11pub struct ReadLock<'a, Element> {
32 id: Id,
33 _marker: PhantomData<(&'a Element, *const ())>,
34}
35
36impl<'a, Element> ReadLock<'a, Element> {
37 pub(super) unsafe fn new(id: Id) -> Self {
38 Self {
39 id,
40 _marker: PhantomData::default(),
41 }
42 }
43}
44
45impl<'a, Element> Deref for ReadLock<'a, Element> {
46 type Target = Element;
47
48 fn deref(&self) -> &Element {
49 unsafe { Block::get_unchecked(self.id).as_ref() }
50 }
51}
52
53impl<'a, Element> Drop for ReadLock<'a, Element> {
54 fn drop(&mut self) {
55 unsafe {
56 Block::<Element>::unlock_read(self.id);
57 }
58 }
59}
60
61impl<'a, Element: Debug> Debug for ReadLock<'a, Element> {
62 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
63 Debug::fmt(self.deref(), f)
64 }
65}
66
67impl<'a, Element: Display> Display for ReadLock<'a, Element> {
68 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
69 Display::fmt(self.deref(), f)
70 }
71}
72
73unsafe impl<'a, Element: Sync> Sync for ReadLock<'a, Element> {}
74
75pub struct WriteLock<'a, Element> {
97 id: Id,
98 _marker: PhantomData<(&'a Element, *const ())>,
99}
100
101impl<'a, Element> WriteLock<'a, Element> {
102 pub(super) unsafe fn new(id: Id) -> Self {
103 Self {
104 id,
105 _marker: PhantomData::default(),
106 }
107 }
108
109 pub(super) fn forget(self) -> Id {
110 let result = self.id;
111 mem::forget(self);
112 result
113 }
114}
115
116impl<'a, Element> Deref for WriteLock<'a, Element> {
117 type Target = Element;
118
119 fn deref(&self) -> &Element {
120 unsafe { Block::get_unchecked(self.id).as_ref() }
121 }
122}
123
124impl<'a, Element> DerefMut for WriteLock<'a, Element> {
125 fn deref_mut(&mut self) -> &mut Element {
126 unsafe { Block::get_unchecked(self.id).as_mut() }
127 }
128}
129
130impl<'a, Element> Drop for WriteLock<'a, Element> {
131 fn drop(&mut self) {
132 unsafe { Block::<Element>::unlock_write(self.id) }
133 }
134}
135
136impl<'a, Element: Debug> Debug for WriteLock<'a, Element> {
137 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
138 Debug::fmt(self.deref(), f)
139 }
140}
141
142impl<'a, Element: Display> Display for WriteLock<'a, Element> {
143 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
144 Display::fmt(self.deref(), f)
145 }
146}
147
148unsafe impl<'a, Element: Sync> Sync for WriteLock<'a, Element> {}
149
150#[cfg(test)]
151mod test {
152 use crate::RwStore;
153 use std::panic::{RefUnwindSafe, UnwindSafe};
154
155 #[test]
156 fn read_lock_implements_sync() {
157 let store = RwStore::new();
158 let id = store.insert(42);
159 let lock = store.read(id).unwrap();
160 &lock as &dyn Sync;
161 }
162
163 #[test]
164 fn write_lock_implements_sync() {
165 let store = RwStore::new();
166 let id = store.insert(42);
167 let lock = store.write(id).unwrap();
168 &lock as &dyn Sync;
169 }
170
171 #[test]
172 fn read_lock_implements_unwind_safe() {
173 let store = RwStore::new();
174 let id = store.insert(42);
175 let lock = store.read(id).unwrap();
176 &lock as &dyn UnwindSafe;
177 }
178
179 #[test]
180 fn write_lock_implements_unwind_safe() {
181 let store = RwStore::new();
182 let id = store.insert(42);
183 let lock = store.write(id).unwrap();
184 &lock as &dyn UnwindSafe;
185 }
186
187 #[test]
188 fn read_lock_implements_ref_unwind_safe() {
189 let store = RwStore::new();
190 let id = store.insert(42);
191 let lock = store.read(id).unwrap();
192 &lock as &dyn RefUnwindSafe;
193 }
194
195 #[test]
196 fn write_lock_implements_ref_unwind_safe() {
197 let store = RwStore::new();
198 let id = store.insert(42);
199 let lock = store.write(id).unwrap();
200 &lock as &dyn RefUnwindSafe;
201 }
202}
203
204mod doctest {
205 #[test]
213 fn read_lock_doesnt_implement_send() {}
214
215 #[test]
223 fn write_lock_doesnt_implement_send() {}
224}