rustpython_common/lock/
immutable_mutex.rs1#![allow(clippy::needless_lifetimes)]
2
3use alloc::fmt;
4use core::{marker::PhantomData, ops::Deref};
5use lock_api::{MutexGuard, RawMutex};
6
7pub struct ImmutableMappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
11 raw: &'a R,
12 data: *const T,
13 _marker: PhantomData<(&'a T, R::GuardMarker)>,
14}
15
16impl<'a, R: RawMutex, T: ?Sized> MapImmutable<'a, R, T> for MutexGuard<'a, R, T> {
20 fn map_immutable<U: ?Sized, F>(s: Self, f: F) -> ImmutableMappedMutexGuard<'a, R, U>
21 where
22 F: FnOnce(&T) -> &U,
23 {
24 let raw = unsafe { MutexGuard::mutex(&s).raw() };
25 let data = f(&s) as *const U;
26 core::mem::forget(s);
27 ImmutableMappedMutexGuard {
28 raw,
29 data,
30 _marker: PhantomData,
31 }
32 }
33}
34
35impl<'a, R: RawMutex, T: ?Sized> ImmutableMappedMutexGuard<'a, R, T> {
36 pub fn map<U: ?Sized, F>(s: Self, f: F) -> ImmutableMappedMutexGuard<'a, R, U>
37 where
38 F: FnOnce(&T) -> &U,
39 {
40 let raw = s.raw;
41 let data = f(&s) as *const U;
42 core::mem::forget(s);
43 ImmutableMappedMutexGuard {
44 raw,
45 data,
46 _marker: PhantomData,
47 }
48 }
49}
50
51impl<R: RawMutex, T: ?Sized> Deref for ImmutableMappedMutexGuard<'_, R, T> {
52 type Target = T;
53 fn deref(&self) -> &Self::Target {
54 unsafe { &*self.data }
56 }
57}
58
59impl<R: RawMutex, T: ?Sized> Drop for ImmutableMappedMutexGuard<'_, R, T> {
60 fn drop(&mut self) {
61 unsafe { self.raw.unlock() }
63 }
64}
65
66impl<R: RawMutex, T: fmt::Debug + ?Sized> fmt::Debug for ImmutableMappedMutexGuard<'_, R, T> {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 fmt::Debug::fmt(&**self, f)
69 }
70}
71
72impl<R: RawMutex, T: fmt::Display + ?Sized> fmt::Display for ImmutableMappedMutexGuard<'_, R, T> {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 fmt::Display::fmt(&**self, f)
75 }
76}
77
78pub trait MapImmutable<'a, R: RawMutex, T: ?Sized> {
79 fn map_immutable<U: ?Sized, F>(s: Self, f: F) -> ImmutableMappedMutexGuard<'a, R, U>
80 where
81 F: FnOnce(&T) -> &U;
82}