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