jsave/
mutex.rs

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}