1use crate::lock::{
2 MapImmutable, PyImmutableMappedMutexGuard, PyMappedMutexGuard, PyMappedRwLockReadGuard,
3 PyMappedRwLockWriteGuard, PyMutexGuard, PyRwLockReadGuard, PyRwLockWriteGuard,
4};
5use std::{
6 fmt,
7 ops::{Deref, DerefMut},
8};
9
10macro_rules! impl_from {
11 ($lt:lifetime, $gen:ident, $t:ty, $($var:ident($from:ty),)*) => {
12 $(
13 impl<$lt, $gen: ?Sized> From<$from> for $t {
14 fn from(t: $from) -> Self {
15 Self::$var(t)
16 }
17 }
18 )*
19 };
20}
21
22#[derive(Debug)]
23pub enum BorrowedValue<'a, T: ?Sized> {
24 Ref(&'a T),
25 MuLock(PyMutexGuard<'a, T>),
26 MappedMuLock(PyImmutableMappedMutexGuard<'a, T>),
27 ReadLock(PyRwLockReadGuard<'a, T>),
28 MappedReadLock(PyMappedRwLockReadGuard<'a, T>),
29}
30impl_from!('a, T, BorrowedValue<'a, T>,
31 Ref(&'a T),
32 MuLock(PyMutexGuard<'a, T>),
33 MappedMuLock(PyImmutableMappedMutexGuard<'a, T>),
34 ReadLock(PyRwLockReadGuard<'a, T>),
35 MappedReadLock(PyMappedRwLockReadGuard<'a, T>),
36);
37
38impl<'a, T: ?Sized> BorrowedValue<'a, T> {
39 pub fn map<U: ?Sized, F>(s: Self, f: F) -> BorrowedValue<'a, U>
40 where
41 F: FnOnce(&T) -> &U,
42 {
43 match s {
44 Self::Ref(r) => BorrowedValue::Ref(f(r)),
45 Self::MuLock(m) => BorrowedValue::MappedMuLock(PyMutexGuard::map_immutable(m, f)),
46 Self::MappedMuLock(m) => {
47 BorrowedValue::MappedMuLock(PyImmutableMappedMutexGuard::map(m, f))
48 }
49 Self::ReadLock(r) => BorrowedValue::MappedReadLock(PyRwLockReadGuard::map(r, f)),
50 Self::MappedReadLock(m) => {
51 BorrowedValue::MappedReadLock(PyMappedRwLockReadGuard::map(m, f))
52 }
53 }
54 }
55}
56
57impl<T: ?Sized> Deref for BorrowedValue<'_, T> {
58 type Target = T;
59 fn deref(&self) -> &T {
60 match self {
61 Self::Ref(r) => r,
62 Self::MuLock(m) => m,
63 Self::MappedMuLock(m) => m,
64 Self::ReadLock(r) => r,
65 Self::MappedReadLock(m) => m,
66 }
67 }
68}
69
70impl fmt::Display for BorrowedValue<'_, str> {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 fmt::Display::fmt(self.deref(), f)
73 }
74}
75
76#[derive(Debug)]
77pub enum BorrowedValueMut<'a, T: ?Sized> {
78 RefMut(&'a mut T),
79 MuLock(PyMutexGuard<'a, T>),
80 MappedMuLock(PyMappedMutexGuard<'a, T>),
81 WriteLock(PyRwLockWriteGuard<'a, T>),
82 MappedWriteLock(PyMappedRwLockWriteGuard<'a, T>),
83}
84impl_from!('a, T, BorrowedValueMut<'a, T>,
85 RefMut(&'a mut T),
86 MuLock(PyMutexGuard<'a, T>),
87 MappedMuLock(PyMappedMutexGuard<'a, T>),
88 WriteLock(PyRwLockWriteGuard<'a, T>),
89 MappedWriteLock(PyMappedRwLockWriteGuard<'a, T>),
90);
91
92impl<'a, T: ?Sized> BorrowedValueMut<'a, T> {
93 pub fn map<U: ?Sized, F>(s: Self, f: F) -> BorrowedValueMut<'a, U>
94 where
95 F: FnOnce(&mut T) -> &mut U,
96 {
97 match s {
98 Self::RefMut(r) => BorrowedValueMut::RefMut(f(r)),
99 Self::MuLock(m) => BorrowedValueMut::MappedMuLock(PyMutexGuard::map(m, f)),
100 Self::MappedMuLock(m) => BorrowedValueMut::MappedMuLock(PyMappedMutexGuard::map(m, f)),
101 Self::WriteLock(r) => BorrowedValueMut::MappedWriteLock(PyRwLockWriteGuard::map(r, f)),
102 Self::MappedWriteLock(m) => {
103 BorrowedValueMut::MappedWriteLock(PyMappedRwLockWriteGuard::map(m, f))
104 }
105 }
106 }
107}
108
109impl<T: ?Sized> Deref for BorrowedValueMut<'_, T> {
110 type Target = T;
111 fn deref(&self) -> &T {
112 match self {
113 Self::RefMut(r) => r,
114 Self::MuLock(m) => m,
115 Self::MappedMuLock(m) => m,
116 Self::WriteLock(w) => w,
117 Self::MappedWriteLock(w) => w,
118 }
119 }
120}
121
122impl<T: ?Sized> DerefMut for BorrowedValueMut<'_, T> {
123 fn deref_mut(&mut self) -> &mut T {
124 match self {
125 Self::RefMut(r) => r,
126 Self::MuLock(m) => &mut *m,
127 Self::MappedMuLock(m) => &mut *m,
128 Self::WriteLock(w) => &mut *w,
129 Self::MappedWriteLock(w) => &mut *w,
130 }
131 }
132}