rustpython_common/
borrow.rs

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}