1use parking_lot::{
2 MappedMutexGuard as InnerMappedMutexGuard, Mutex as InnerMutex, MutexGuard as InnerMutexGuard,
3};
4use serde::{Deserialize, Serialize};
5use std::{
6 fmt::{Debug, Display, Formatter, Result as FmtResult},
7 fs::OpenOptions,
8 io::Error,
9 ops::{Deref, DerefMut},
10 path::{Path, PathBuf},
11 time::{Duration, Instant},
12};
13
14pub struct Mutex<T: ?Sized> {
15 file_path: PathBuf,
16 data: InnerMutex<T>,
17}
18
19impl<T> Mutex<T>
20where
21 T: Serialize + for<'de> Deserialize<'de> + ?Sized,
22{
23 #[inline]
24 pub fn init<P: Into<PathBuf>>(file_path: P) -> Result<Self, Error> {
25 let file_path = file_path.into();
26
27 let data = {
28 let read = OpenOptions::new().read(true).open(&file_path)?;
29 serde_json::from_reader(read)?
30 };
31
32 crate::save_data_to_path(&data, &file_path)?;
33
34 Ok(Self {
35 data: InnerMutex::new(data),
36 file_path,
37 })
38 }
39
40 #[inline]
41 pub fn init_with<P: Into<PathBuf>>(data: T, file_path: P) -> Result<Self, Error> {
42 let file_path = file_path.into();
43
44 crate::save_data_to_path(&data, &file_path)?;
45
46 Ok(Self {
47 data: InnerMutex::new(data),
48 file_path,
49 })
50 }
51
52 #[inline]
53 pub fn into_inner(self) -> T {
54 self.data.into_inner()
55 }
56
57 #[inline]
58 pub fn path(&self) -> &Path {
59 &self.file_path
60 }
61
62 #[inline]
63 pub fn get_mut(&mut self) -> &mut T {
64 self.data.get_mut()
65 }
66
67 #[inline]
68 pub fn is_locked(&self) -> bool {
69 self.data.is_locked()
70 }
71
72 #[inline]
73 pub fn data_ptr(&self) -> *mut T {
74 self.data.data_ptr()
75 }
76
77 #[inline]
78 pub fn lock(&self) -> MutexGuard<T> {
79 MutexGuard {
80 mutex: self,
81 guard: self.data.lock(),
82 }
83 }
84
85 #[inline]
86 pub fn try_lock(&self) -> Option<MutexGuard<T>> {
87 self.data.try_lock().map(|g| MutexGuard {
88 mutex: self,
89 guard: g,
90 })
91 }
92
93 #[inline]
94 pub fn try_lock_for(&self, timeout: Duration) -> Option<MutexGuard<T>> {
95 self.data.try_lock_for(timeout).map(|g| MutexGuard {
96 mutex: self,
97 guard: g,
98 })
99 }
100
101 #[inline]
102 pub fn try_lock_until(&self, timeout: Instant) -> Option<MutexGuard<T>> {
103 self.data.try_lock_until(timeout).map(|g| MutexGuard {
104 mutex: self,
105 guard: g,
106 })
107 }
108
109 #[inline]
110 pub fn save(&self) -> Result<(), Error> {
111 let data = self.data.lock();
112 crate::save_data_to_path(data.deref(), &self.file_path)
113 }
114
115 #[inline]
116 pub fn try_save(&self) -> Option<Result<(), Error>> {
117 self.data
118 .try_lock()
119 .map(|data| crate::save_data_to_path(data.deref(), &self.file_path))
120 }
121
122 #[inline]
123 pub fn try_save_for(&self, timeout: Duration) -> Option<Result<(), Error>> {
124 self.data
125 .try_lock_for(timeout)
126 .map(|data| crate::save_data_to_path(data.deref(), &self.file_path))
127 }
128
129 #[inline]
130 pub fn try_save_until(&self, timeout: Instant) -> Option<Result<(), Error>> {
131 self.data
132 .try_lock_until(timeout)
133 .map(|data| crate::save_data_to_path(data.deref(), &self.file_path))
134 }
135
136 #[inline]
137 #[allow(clippy::missing_safety_doc)]
138 pub unsafe fn force_unlock(&self) {
139 self.data.force_unlock()
140 }
141
142 #[inline]
143 #[allow(clippy::missing_safety_doc)]
144 pub unsafe fn force_unlock_fair(&self) {
145 self.data.force_unlock_fair()
146 }
147}
148
149impl<T> Debug for Mutex<T>
150where
151 T: Debug + Serialize + for<'de> Deserialize<'de> + ?Sized,
152{
153 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
154 self.data.fmt(f)
155 }
156}
157
158pub struct MutexGuard<'a, T: ?Sized> {
159 mutex: &'a Mutex<T>,
160 guard: InnerMutexGuard<'a, T>,
161}
162
163impl<'a, T: ?Sized> MutexGuard<'a, T> {
164 #[inline]
165 pub fn mutex(s: &Self) -> &'a Mutex<T> {
166 s.mutex
167 }
168
169 #[inline]
170 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, U>
171 where
172 F: FnOnce(&mut T) -> &mut U,
173 {
174 MappedMutexGuard(InnerMutexGuard::map(s.guard, f))
175 }
176
177 #[inline]
178 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
179 where
180 F: FnOnce(&mut T) -> Option<&mut U>,
181 {
182 InnerMutexGuard::try_map(s.guard, f).map_or_else(
183 |g| {
184 Err(Self {
185 mutex: s.mutex,
186 guard: g,
187 })
188 },
189 |g| Ok(MappedMutexGuard(g)),
190 )
191 }
192
193 #[inline]
194 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
195 where
196 F: FnOnce() -> U,
197 {
198 InnerMutexGuard::unlocked(&mut s.guard, f)
199 }
200
201 #[inline]
202 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
203 where
204 F: FnOnce() -> U,
205 {
206 InnerMutexGuard::unlocked_fair(&mut s.guard, f)
207 }
208
209 #[inline]
210 pub fn unlock_fair(s: Self) {
211 InnerMutexGuard::unlock_fair(s.guard);
212 }
213
214 #[inline]
215 pub fn bump(s: &mut Self) {
216 InnerMutexGuard::bump(&mut s.guard);
217 }
218}
219
220impl<T> Debug for MutexGuard<'_, T>
221where
222 T: Debug + ?Sized,
223{
224 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
225 self.guard.fmt(f)
226 }
227}
228
229impl<T> Display for MutexGuard<'_, T>
230where
231 T: Display + ?Sized,
232{
233 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
234 self.guard.fmt(f)
235 }
236}
237
238impl<T: ?Sized + Serialize> Deref for MutexGuard<'_, T> {
239 type Target = T;
240
241 #[inline]
242 fn deref(&self) -> &Self::Target {
243 self.guard.deref()
244 }
245}
246
247impl<T: ?Sized + Serialize> DerefMut for MutexGuard<'_, T> {
248 #[inline]
249 fn deref_mut(&mut self) -> &mut T {
250 self.guard.deref_mut()
251 }
252}
253
254pub struct MappedMutexGuard<'a, T: ?Sized>(InnerMappedMutexGuard<'a, T>);
255
256impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
257 #[inline]
258 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, U>
259 where
260 F: FnOnce(&mut T) -> &mut U,
261 {
262 MappedMutexGuard(InnerMappedMutexGuard::map(s.0, f))
263 }
264
265 #[inline]
266 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
267 where
268 F: FnOnce(&mut T) -> Option<&mut U>,
269 {
270 InnerMappedMutexGuard::try_map(s.0, f)
271 .map_or_else(|g| Err(Self(g)), |g| Ok(MappedMutexGuard(g)))
272 }
273
274 #[inline]
275 pub fn unlock_fair(s: Self) {
276 InnerMappedMutexGuard::unlock_fair(s.0);
277 }
278}
279
280impl<T> Debug for MappedMutexGuard<'_, T>
281where
282 T: Debug + ?Sized,
283{
284 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
285 self.0.fmt(f)
286 }
287}
288
289impl<T> Display for MappedMutexGuard<'_, T>
290where
291 T: Display + ?Sized,
292{
293 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
294 self.0.fmt(f)
295 }
296}
297
298impl<T: ?Sized + Serialize> Deref for MappedMutexGuard<'_, T> {
299 type Target = T;
300
301 #[inline]
302 fn deref(&self) -> &Self::Target {
303 self.0.deref()
304 }
305}
306
307impl<T: ?Sized + Serialize> DerefMut for MappedMutexGuard<'_, T> {
308 #[inline]
309 fn deref_mut(&mut self) -> &mut T {
310 self.0.deref_mut()
311 }
312}