1use crate::lock::{
2 MapImmutable, PyImmutableMappedMutexGuard, PyMappedDetachingRwLockReadGuard,
3 PyMappedDetachingRwLockWriteGuard, PyMappedMutexGuard, PyMappedRwLockReadGuard,
4 PyMappedRwLockWriteGuard, PyMutexGuard, PyRwLockReadGuard, PyRwLockWriteGuard,
5};
6use alloc::fmt;
7use core::ops::{Deref, DerefMut};
8
9macro_rules! impl_from {
10 ($lt:lifetime, $gen:ident, $t:ty, $($var:ident($from:ty),)*) => {
11 $(
12 impl<$lt, $gen: ?Sized> From<$from> for $t {
13 fn from(t: $from) -> Self {
14 Self::$var(t)
15 }
16 }
17 )*
18 };
19}
20
21#[derive(Debug)]
22pub enum BorrowedValue<'a, T: ?Sized> {
23 Ref(&'a T),
24 MuLock(PyMutexGuard<'a, T>),
25 MappedMuLock(PyImmutableMappedMutexGuard<'a, T>),
26 ReadLock(PyRwLockReadGuard<'a, T>),
27 MappedReadLock(PyMappedRwLockReadGuard<'a, T>),
28 MappedDetachingReadLock(PyMappedDetachingRwLockReadGuard<'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 MappedDetachingReadLock(PyMappedDetachingRwLockReadGuard<'a, T>),
37);
38
39impl<'a, T: ?Sized> BorrowedValue<'a, T> {
40 #[must_use]
47 pub const fn is_locked(&self) -> bool {
48 !matches!(self, Self::Ref(_))
49 }
50
51 pub fn map<U: ?Sized, F>(s: Self, f: F) -> BorrowedValue<'a, U>
52 where
53 F: FnOnce(&T) -> &U,
54 {
55 match s {
56 Self::Ref(r) => BorrowedValue::Ref(f(r)),
57 Self::MuLock(m) => BorrowedValue::MappedMuLock(PyMutexGuard::map_immutable(m, f)),
58 Self::MappedMuLock(m) => {
59 BorrowedValue::MappedMuLock(PyImmutableMappedMutexGuard::map(m, f))
60 }
61 Self::ReadLock(r) => BorrowedValue::MappedReadLock(PyRwLockReadGuard::map(r, f)),
62 Self::MappedReadLock(m) => {
63 BorrowedValue::MappedReadLock(PyMappedRwLockReadGuard::map(m, f))
64 }
65 Self::MappedDetachingReadLock(m) => {
66 BorrowedValue::MappedDetachingReadLock(PyMappedDetachingRwLockReadGuard::map(m, f))
67 }
68 }
69 }
70}
71
72impl<T: ?Sized> Deref for BorrowedValue<'_, T> {
73 type Target = T;
74
75 fn deref(&self) -> &T {
76 match self {
77 Self::Ref(r) => r,
78 Self::MuLock(m) => m,
79 Self::MappedMuLock(m) => m,
80 Self::ReadLock(r) => r,
81 Self::MappedReadLock(m) => m,
82 Self::MappedDetachingReadLock(m) => m,
83 }
84 }
85}
86
87impl fmt::Display for BorrowedValue<'_, str> {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 fmt::Display::fmt(&**self, f)
90 }
91}
92
93#[derive(Debug)]
94pub enum BorrowedValueMut<'a, T: ?Sized> {
95 RefMut(&'a mut T),
96 MuLock(PyMutexGuard<'a, T>),
97 MappedMuLock(PyMappedMutexGuard<'a, T>),
98 WriteLock(PyRwLockWriteGuard<'a, T>),
99 MappedWriteLock(PyMappedRwLockWriteGuard<'a, T>),
100 MappedDetachingWriteLock(PyMappedDetachingRwLockWriteGuard<'a, T>),
101}
102
103impl_from!('a, T, BorrowedValueMut<'a, T>,
104 RefMut(&'a mut T),
105 MuLock(PyMutexGuard<'a, T>),
106 MappedMuLock(PyMappedMutexGuard<'a, T>),
107 WriteLock(PyRwLockWriteGuard<'a, T>),
108 MappedWriteLock(PyMappedRwLockWriteGuard<'a, T>),
109 MappedDetachingWriteLock(PyMappedDetachingRwLockWriteGuard<'a, T>),
110);
111
112impl<'a, T: ?Sized> BorrowedValueMut<'a, T> {
113 pub fn map<U: ?Sized, F>(s: Self, f: F) -> BorrowedValueMut<'a, U>
114 where
115 F: FnOnce(&mut T) -> &mut U,
116 {
117 match s {
118 Self::RefMut(r) => BorrowedValueMut::RefMut(f(r)),
119 Self::MuLock(m) => BorrowedValueMut::MappedMuLock(PyMutexGuard::map(m, f)),
120 Self::MappedMuLock(m) => BorrowedValueMut::MappedMuLock(PyMappedMutexGuard::map(m, f)),
121 Self::WriteLock(r) => BorrowedValueMut::MappedWriteLock(PyRwLockWriteGuard::map(r, f)),
122 Self::MappedWriteLock(m) => {
123 BorrowedValueMut::MappedWriteLock(PyMappedRwLockWriteGuard::map(m, f))
124 }
125 Self::MappedDetachingWriteLock(m) => BorrowedValueMut::MappedDetachingWriteLock(
126 PyMappedDetachingRwLockWriteGuard::map(m, f),
127 ),
128 }
129 }
130}
131
132impl<T: ?Sized> Deref for BorrowedValueMut<'_, T> {
133 type Target = T;
134
135 fn deref(&self) -> &T {
136 match self {
137 Self::RefMut(r) => r,
138 Self::MuLock(m) => m,
139 Self::MappedMuLock(m) => m,
140 Self::WriteLock(w) => w,
141 Self::MappedWriteLock(w) => w,
142 Self::MappedDetachingWriteLock(w) => w,
143 }
144 }
145}
146
147impl<T: ?Sized> DerefMut for BorrowedValueMut<'_, T> {
148 fn deref_mut(&mut self) -> &mut T {
149 match self {
150 Self::RefMut(r) => r,
151 Self::MuLock(m) => &mut *m,
152 Self::MappedMuLock(m) => &mut *m,
153 Self::WriteLock(w) => &mut *w,
154 Self::MappedWriteLock(w) => &mut *w,
155 Self::MappedDetachingWriteLock(w) => &mut *w,
156 }
157 }
158}