1use std::convert::Infallible;
10use std::error::Error;
11use std::fmt::{Debug, Display, Formatter};
12use std::mem::replace;
13use std::ops::{Deref, DerefMut};
14
15use parking_lot::{
16 MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
17};
18use pyo3::exceptions::PyRuntimeError;
19use pyo3::PyErr;
20
21const CONSUMED_ERROR_MSG: &str = "Already consumed";
22const LOCK_ERROR_MSG: &str = "Already mutably borrowed";
23
24#[derive(Debug)]
26pub struct ConsumedError;
27
28impl Display for ConsumedError {
29 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
30 write!(f, "{CONSUMED_ERROR_MSG}")
31 }
32}
33
34impl Error for ConsumedError {}
35
36impl From<ConsumedError> for PyErr {
37 fn from(_: ConsumedError) -> Self {
38 PyRuntimeError::new_err(CONSUMED_ERROR_MSG)
39 }
40}
41
42pub type ConsumedResult<T> = Result<T, ConsumedError>;
43
44#[derive(Debug)]
47pub struct LockError;
48
49impl Display for LockError {
50 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51 write!(f, "{LOCK_ERROR_MSG}")
52 }
53}
54
55impl Error for LockError {}
56
57impl From<LockError> for PyErr {
58 fn from(_: LockError) -> Self {
59 PyRuntimeError::new_err(LOCK_ERROR_MSG)
60 }
61}
62
63pub type LockResult<T> = Result<T, LockError>;
64
65pub type PyWrapperT0<T> = Result<T, Infallible>;
67pub type PyWrapperT1<T> = RwLock<Result<T, Infallible>>;
79pub type PyWrapperT2<T> = RwLock<Result<T, ConsumedError>>;
81
82mod sealed {
83 use super::*;
84
85 pub trait PyWrapperT {}
86
87 impl<T> PyWrapperT for PyWrapperT0<T> {}
88 impl<T> PyWrapperT for PyWrapperT1<T> {}
89 impl<T> PyWrapperT for PyWrapperT2<T> {}
90
91 pub trait SealedPyWrapper {}
92
93 impl<T> SealedPyWrapper for PyWrapper<T> where T: PyWrapperT {}
94
95 pub trait SealedMappableDeref {}
96
97 impl<T: ?Sized> SealedMappableDeref for &T {}
98 impl<T: ?Sized> SealedMappableDeref for RwLockReadGuard<'_, T> {}
99 impl<T: ?Sized> SealedMappableDeref for MappedRwLockReadGuard<'_, T> {}
100
101 pub trait SealedMappableDerefMut {}
102
103 impl<T: ?Sized> SealedMappableDerefMut for &mut T {}
104 impl<T: ?Sized> SealedMappableDerefMut for RwLockWriteGuard<'_, T> {}
105 impl<T: ?Sized> SealedMappableDerefMut for MappedRwLockWriteGuard<'_, T> {}
106}
107
108trait RwLockExt {
109 type T;
110
111 fn try_read_ext(&self) -> LockResult<RwLockReadGuard<'_, Self::T>>;
112
113 fn try_write_ext(&self) -> LockResult<RwLockWriteGuard<'_, Self::T>>;
114}
115
116impl<T> RwLockExt for RwLock<T> {
117 type T = T;
118
119 fn try_read_ext(&self) -> LockResult<RwLockReadGuard<'_, T>> {
120 self.try_read().ok_or(LockError)
121 }
122
123 fn try_write_ext(&self) -> LockResult<RwLockWriteGuard<'_, T>> {
124 self.try_write().ok_or(LockError)
125 }
126}
127
128pub trait MappableDeref<'a>: Deref + sealed::SealedMappableDeref {
130 fn map<U, F>(self, f: F) -> impl MappableDeref<'a, Target = U>
132 where
133 U: ?Sized + 'a,
134 F: FnOnce(&Self::Target) -> &U;
135}
136
137impl<'a, T> MappableDeref<'a> for &'a T
138where
139 T: ?Sized,
140{
141 fn map<U, F>(self, f: F) -> impl MappableDeref<'a, Target = U>
142 where
143 U: ?Sized + 'a,
144 F: FnOnce(&T) -> &U,
145 {
146 f(self)
147 }
148}
149
150impl<'a, T> MappableDeref<'a> for MappedRwLockReadGuard<'a, T>
151where
152 T: ?Sized + 'a,
153{
154 fn map<U, F>(self, f: F) -> impl MappableDeref<'a, Target = U>
155 where
156 U: ?Sized + 'a,
157 F: FnOnce(&T) -> &U,
158 {
159 MappedRwLockReadGuard::map(self, f)
160 }
161}
162
163impl<'a, T> MappableDeref<'a> for RwLockReadGuard<'a, T>
164where
165 T: ?Sized + 'a,
166{
167 fn map<U, F>(self, f: F) -> impl MappableDeref<'a, Target = U>
168 where
169 U: ?Sized + 'a,
170 F: FnOnce(&T) -> &U,
171 {
172 RwLockReadGuard::map(self, f)
173 }
174}
175
176pub trait MappableDerefMut<'a>: DerefMut + sealed::SealedMappableDerefMut {
178 fn map<U, F>(self, f: F) -> impl MappableDerefMut<'a, Target = U>
180 where
181 U: ?Sized + 'a,
182 F: FnOnce(&mut Self::Target) -> &mut U;
183}
184
185impl<'a, T> MappableDerefMut<'a> for &'a mut T
186where
187 T: ?Sized,
188{
189 fn map<U, F>(self, f: F) -> impl MappableDerefMut<'a, Target = U>
190 where
191 U: ?Sized + 'a,
192 F: FnOnce(&mut T) -> &mut U,
193 {
194 f(self)
195 }
196}
197
198impl<'a, T> MappableDerefMut<'a> for MappedRwLockWriteGuard<'a, T>
199where
200 T: ?Sized + 'a,
201{
202 fn map<U, F>(self, f: F) -> impl MappableDerefMut<'a, Target = U>
203 where
204 U: ?Sized + 'a,
205 F: FnOnce(&mut T) -> &mut U,
206 {
207 MappedRwLockWriteGuard::map(self, f)
208 }
209}
210
211impl<'a, T> MappableDerefMut<'a> for RwLockWriteGuard<'a, T>
212where
213 T: ?Sized + 'a,
214{
215 fn map<U, F>(self, f: F) -> impl MappableDerefMut<'a, Target = U>
216 where
217 U: ?Sized + 'a,
218 F: FnOnce(&mut T) -> &mut U,
219 {
220 RwLockWriteGuard::map(self, f)
221 }
222}
223
224pub struct PyWrapper<T>
266where
267 T: sealed::PyWrapperT,
268{
269 inner: T,
270}
271
272impl<T> PyWrapper<PyWrapperT0<T>> {
273 #[inline]
274 pub fn new0(inner: T) -> Self {
275 Self { inner: Ok(inner) }
276 }
277
278 #[inline]
279 pub fn inner_ref(&self) -> impl MappableDeref<'_, Target = T> {
280 self.inner.as_ref().unwrap()
282 }
283
284 #[inline]
285 pub fn inner_mut(&mut self) -> impl MappableDerefMut<'_, Target = T> {
286 self.inner.as_mut().unwrap()
288 }
289
290 #[inline]
291 pub fn into_inner(self) -> T {
292 self.inner.unwrap()
294 }
295}
296
297impl<T> PyWrapper<PyWrapperT1<T>> {
298 #[inline]
299 pub fn new1(inner: T) -> Self {
300 Self {
301 inner: RwLock::new(Ok(inner)),
302 }
303 }
304
305 pub fn lock_inner_ref(&self) -> LockResult<MappedRwLockReadGuard<'_, T>> {
306 self.inner
307 .try_read_ext()
308 .map(|guard| RwLockReadGuard::map(guard, |inner| inner.as_ref().unwrap()))
310 }
311
312 pub fn lock_inner_mut(&self) -> LockResult<MappedRwLockWriteGuard<'_, T>> {
313 self.inner
314 .try_write_ext()
315 .map(|guard| RwLockWriteGuard::map(guard, |inner| inner.as_mut().unwrap()))
317 }
318
319 pub fn into_inner(self) -> T {
320 self.inner.into_inner().unwrap()
322 }
323
324 #[deprecated(note = "use `lock_inner_ref` instead")]
328 pub fn inner_ref(&self) -> impl MappableDeref<'_, Target = T> {
329 self.lock_inner_ref().expect(LOCK_ERROR_MSG)
330 }
331
332 #[deprecated(note = "use `lock_inner_mut` instead")]
336 pub fn inner_mut(&self) -> impl MappableDerefMut<'_, Target = T> {
337 self.lock_inner_mut().expect(LOCK_ERROR_MSG)
338 }
339}
340
341impl<T> PyWrapper<PyWrapperT2<T>> {
342 #[inline]
343 pub fn new2(inner: T) -> Self {
344 Self {
345 inner: RwLock::new(Ok(inner)),
346 }
347 }
348
349 pub fn try_lock_inner_ref(&self) -> LockResult<ConsumedResult<MappedRwLockReadGuard<'_, T>>> {
350 self.try_read().map(|guard| {
351 if guard.is_err() {
352 Err(ConsumedError)
353 } else {
354 Ok(RwLockReadGuard::map(guard, |inner| inner.as_ref().unwrap()))
356 }
357 })
358 }
359
360 pub fn try_lock_inner_mut(&self) -> LockResult<ConsumedResult<MappedRwLockWriteGuard<'_, T>>> {
361 self.try_write().map(|guard| {
362 if guard.is_err() {
363 Err(ConsumedError)
364 } else {
365 Ok(RwLockWriteGuard::map(guard, |inner| {
367 inner.as_mut().unwrap()
368 }))
369 }
370 })
371 }
372
373 pub fn try_take_inner(&self) -> LockResult<ConsumedResult<T>> {
374 self.try_replace_inner(Err(ConsumedError))
375 }
376
377 pub fn try_replace_inner(&self, inner: ConsumedResult<T>) -> LockResult<ConsumedResult<T>> {
379 self.try_write().map(|mut guard| {
380 let result = guard.deref_mut();
381 replace(result, inner)
382 })
383 }
384
385 pub fn try_read(&self) -> LockResult<RwLockReadGuard<'_, ConsumedResult<T>>> {
387 self.inner.try_read_ext()
388 }
389
390 pub fn try_write(&self) -> LockResult<RwLockWriteGuard<'_, ConsumedResult<T>>> {
392 self.inner.try_write_ext()
393 }
394
395 pub fn try_into_inner(self) -> ConsumedResult<T> {
396 self.inner.into_inner()
397 }
398
399 #[deprecated(note = "use `try_lock_inner_ref` instead")]
403 pub fn lock_inner_ref(&self) -> LockResult<MappedRwLockReadGuard<'_, T>> {
404 self.try_lock_inner_ref()
405 .map(|result| result.expect(CONSUMED_ERROR_MSG))
406 }
407
408 #[deprecated(note = "use `try_lock_inner_mut` instead")]
412 pub fn lock_inner_mut(&self) -> LockResult<MappedRwLockWriteGuard<'_, T>> {
413 self.try_lock_inner_mut()
414 .map(|result| result.expect(CONSUMED_ERROR_MSG))
415 }
416
417 #[deprecated(note = "use `try_lock_inner_ref` instead")]
421 pub fn inner_ref(&self) -> impl MappableDeref<'_, Target = T> {
422 self.try_lock_inner_ref()
423 .expect(LOCK_ERROR_MSG)
424 .expect(CONSUMED_ERROR_MSG)
425 }
426
427 #[deprecated(note = "use `try_lock_inner_mut` instead")]
431 pub fn inner_mut(&self) -> impl MappableDerefMut<'_, Target = T> {
432 self.try_lock_inner_mut()
433 .expect(LOCK_ERROR_MSG)
434 .expect(CONSUMED_ERROR_MSG)
435 }
436
437 #[deprecated(note = "use `try_into_inner` instead")]
441 pub fn into_inner(self) -> T {
442 self.try_into_inner().expect(CONSUMED_ERROR_MSG)
443 }
444}
445
446pub trait PyWrapperSemverExt: sealed::SealedPyWrapper {
457 type Wrapped;
458
459 fn inner_ref_semver(
461 &self,
462 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>>;
463 fn inner_mut_semver(
465 &mut self,
466 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>>;
467 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped>;
468}
469
470impl<T> PyWrapperSemverExt for PyWrapper<PyWrapperT0<T>> {
471 type Wrapped = T;
472
473 fn inner_ref_semver(
474 &self,
475 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>> {
476 Ok(Ok(self.inner_ref()))
477 }
478
479 fn inner_mut_semver(
480 &mut self,
481 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>> {
482 Ok(Ok(self.inner_mut()))
483 }
484
485 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped> {
486 Ok(self.into_inner())
487 }
488}
489
490impl<T> PyWrapperSemverExt for PyWrapper<PyWrapperT1<T>> {
491 type Wrapped = T;
492
493 fn inner_ref_semver(
494 &self,
495 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>> {
496 self.lock_inner_ref().map(Ok)
497 }
498
499 fn inner_mut_semver(
500 &mut self,
501 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>> {
502 self.lock_inner_mut().map(Ok)
503 }
504
505 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped> {
506 Ok(self.into_inner())
507 }
508}
509
510impl<T> PyWrapperSemverExt for PyWrapper<PyWrapperT2<T>> {
511 type Wrapped = T;
512
513 fn inner_ref_semver(
514 &self,
515 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>> {
516 self.try_lock_inner_ref()
517 }
518
519 fn inner_mut_semver(
520 &mut self,
521 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>> {
522 self.try_lock_inner_mut()
523 }
524
525 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped> {
526 self.try_into_inner()
527 }
528}