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 match self.inner.as_ref() {
282 Ok(inner) => inner,
283 Err(infallible) => match *infallible {},
286 }
287 }
288
289 #[inline]
290 pub fn inner_mut(&mut self) -> impl MappableDerefMut<'_, Target = T> {
291 match self.inner.as_mut() {
293 Ok(inner) => inner,
294 Err(infallible) => match *infallible {},
295 }
296 }
297
298 #[inline]
299 pub fn into_inner(self) -> T {
300 let Ok(inner) = self.inner;
302 inner
303 }
304}
305
306impl<T> PyWrapper<PyWrapperT1<T>> {
307 #[inline]
308 pub fn new1(inner: T) -> Self {
309 Self {
310 inner: RwLock::new(Ok(inner)),
311 }
312 }
313
314 pub fn lock_inner_ref(&self) -> LockResult<MappedRwLockReadGuard<'_, T>> {
315 self.inner
316 .try_read_ext()
317 .map(|guard| {
319 RwLockReadGuard::map(guard, |inner| match inner.as_ref() {
320 Ok(inner) => inner,
321 Err(infallible) => match *infallible {},
322 })
323 })
324 }
325
326 pub fn lock_inner_mut(&self) -> LockResult<MappedRwLockWriteGuard<'_, T>> {
327 self.inner
328 .try_write_ext()
329 .map(|guard| {
331 RwLockWriteGuard::map(guard, |inner| match inner.as_mut() {
332 Ok(inner) => inner,
333 Err(infallible) => match *infallible {},
334 })
335 })
336 }
337
338 pub fn into_inner(self) -> T {
339 let Ok(inner) = self.inner.into_inner();
341 inner
342 }
343
344 #[deprecated(note = "use `lock_inner_ref` instead")]
348 pub fn inner_ref(&self) -> impl MappableDeref<'_, Target = T> {
349 self.lock_inner_ref().expect(LOCK_ERROR_MSG)
350 }
351
352 #[deprecated(note = "use `lock_inner_mut` instead")]
356 pub fn inner_mut(&self) -> impl MappableDerefMut<'_, Target = T> {
357 self.lock_inner_mut().expect(LOCK_ERROR_MSG)
358 }
359}
360
361impl<T> PyWrapper<PyWrapperT2<T>> {
362 #[inline]
363 pub fn new2(inner: T) -> Self {
364 Self {
365 inner: RwLock::new(Ok(inner)),
366 }
367 }
368
369 pub fn try_lock_inner_ref(&self) -> LockResult<ConsumedResult<MappedRwLockReadGuard<'_, T>>> {
370 self.try_read().map(|guard| {
371 if guard.is_err() {
372 Err(ConsumedError)
373 } else {
374 Ok(RwLockReadGuard::map(guard, |inner| inner.as_ref().unwrap()))
376 }
377 })
378 }
379
380 pub fn try_lock_inner_mut(&self) -> LockResult<ConsumedResult<MappedRwLockWriteGuard<'_, T>>> {
381 self.try_write().map(|guard| {
382 if guard.is_err() {
383 Err(ConsumedError)
384 } else {
385 Ok(RwLockWriteGuard::map(guard, |inner| {
387 inner.as_mut().unwrap()
388 }))
389 }
390 })
391 }
392
393 pub fn try_take_inner(&self) -> LockResult<ConsumedResult<T>> {
394 self.try_replace_inner(Err(ConsumedError))
395 }
396
397 pub fn try_replace_inner(&self, inner: ConsumedResult<T>) -> LockResult<ConsumedResult<T>> {
399 self.try_write().map(|mut guard| {
400 let result = guard.deref_mut();
401 replace(result, inner)
402 })
403 }
404
405 pub fn try_read(&self) -> LockResult<RwLockReadGuard<'_, ConsumedResult<T>>> {
407 self.inner.try_read_ext()
408 }
409
410 pub fn try_write(&self) -> LockResult<RwLockWriteGuard<'_, ConsumedResult<T>>> {
412 self.inner.try_write_ext()
413 }
414
415 pub fn try_into_inner(self) -> ConsumedResult<T> {
416 self.inner.into_inner()
417 }
418
419 #[deprecated(note = "use `try_lock_inner_ref` instead")]
423 pub fn lock_inner_ref(&self) -> LockResult<MappedRwLockReadGuard<'_, T>> {
424 self.try_lock_inner_ref()
425 .map(|result| result.expect(CONSUMED_ERROR_MSG))
426 }
427
428 #[deprecated(note = "use `try_lock_inner_mut` instead")]
432 pub fn lock_inner_mut(&self) -> LockResult<MappedRwLockWriteGuard<'_, T>> {
433 self.try_lock_inner_mut()
434 .map(|result| result.expect(CONSUMED_ERROR_MSG))
435 }
436
437 #[deprecated(note = "use `try_lock_inner_ref` instead")]
441 pub fn inner_ref(&self) -> impl MappableDeref<'_, Target = T> {
442 self.try_lock_inner_ref()
443 .expect(LOCK_ERROR_MSG)
444 .expect(CONSUMED_ERROR_MSG)
445 }
446
447 #[deprecated(note = "use `try_lock_inner_mut` instead")]
451 pub fn inner_mut(&self) -> impl MappableDerefMut<'_, Target = T> {
452 self.try_lock_inner_mut()
453 .expect(LOCK_ERROR_MSG)
454 .expect(CONSUMED_ERROR_MSG)
455 }
456
457 #[deprecated(note = "use `try_into_inner` instead")]
461 pub fn into_inner(self) -> T {
462 self.try_into_inner().expect(CONSUMED_ERROR_MSG)
463 }
464}
465
466pub trait PyWrapperSemverExt: sealed::SealedPyWrapper {
477 type Wrapped;
478
479 fn inner_ref_semver(
481 &self,
482 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>>;
483 fn inner_mut_semver(
485 &mut self,
486 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>>;
487 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped>;
488}
489
490impl<T> PyWrapperSemverExt for PyWrapper<PyWrapperT0<T>> {
491 type Wrapped = T;
492
493 fn inner_ref_semver(
494 &self,
495 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>> {
496 Ok(Ok(self.inner_ref()))
497 }
498
499 fn inner_mut_semver(
500 &mut self,
501 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>> {
502 Ok(Ok(self.inner_mut()))
503 }
504
505 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped> {
506 Ok(self.into_inner())
507 }
508}
509
510impl<T> PyWrapperSemverExt for PyWrapper<PyWrapperT1<T>> {
511 type Wrapped = T;
512
513 fn inner_ref_semver(
514 &self,
515 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>> {
516 self.lock_inner_ref().map(Ok)
517 }
518
519 fn inner_mut_semver(
520 &mut self,
521 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>> {
522 self.lock_inner_mut().map(Ok)
523 }
524
525 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped> {
526 Ok(self.into_inner())
527 }
528}
529
530impl<T> PyWrapperSemverExt for PyWrapper<PyWrapperT2<T>> {
531 type Wrapped = T;
532
533 fn inner_ref_semver(
534 &self,
535 ) -> LockResult<ConsumedResult<impl MappableDeref<'_, Target = Self::Wrapped>>> {
536 self.try_lock_inner_ref()
537 }
538
539 fn inner_mut_semver(
540 &mut self,
541 ) -> LockResult<ConsumedResult<impl MappableDerefMut<'_, Target = Self::Wrapped>>> {
542 self.try_lock_inner_mut()
543 }
544
545 fn into_inner_semver(self) -> ConsumedResult<Self::Wrapped> {
546 self.try_into_inner()
547 }
548}