Skip to main content

rustpython_common/
borrow.rs

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}