infinity_pool/handles/
blind_local_mut.rs1use std::borrow::{Borrow, BorrowMut};
2use std::cell::RefCell;
3use std::ops::{Deref, DerefMut};
4use std::pin::Pin;
5use std::ptr::NonNull;
6use std::{fmt, mem, ptr};
7
8use crate::{LayoutKey, LocalBlindPoolCore, LocalBlindPooled, RawPooledMut};
9
10#[doc = include_str!("../../doc/snippets/ref_counted_handle_implications.md")]
12#[doc = include_str!("../../doc/snippets/unique_handle_implications.md")]
13pub struct LocalBlindPooledMut<T: ?Sized> {
18 inner: RawPooledMut<T>,
19 key: LayoutKey,
20 core: LocalBlindPoolCore,
21}
22
23impl<T: ?Sized> LocalBlindPooledMut<T> {
24 #[must_use]
25 pub(crate) fn new(inner: RawPooledMut<T>, key: LayoutKey, core: LocalBlindPoolCore) -> Self {
26 Self { inner, key, core }
27 }
28
29 #[doc = include_str!("../../doc/snippets/handle_ptr.md")]
30 #[must_use]
31 #[inline]
32 #[cfg_attr(test, mutants::skip)] pub fn ptr(&self) -> NonNull<T> {
34 self.inner.ptr()
35 }
36
37 #[doc = include_str!("../../doc/snippets/handle_into_shared.md")]
38 #[must_use]
39 #[inline]
40 #[cfg_attr(test, mutants::skip)] pub fn into_shared(self) -> LocalBlindPooled<T> {
42 let (inner, layout, core) = self.into_parts();
43
44 LocalBlindPooled::new(inner, layout, core)
45 }
46
47 #[cfg_attr(test, mutants::skip)] fn into_parts(self) -> (RawPooledMut<T>, LayoutKey, LocalBlindPoolCore) {
49 let inner = unsafe { ptr::read(&raw const self.inner) };
54 let key = unsafe { ptr::read(&raw const self.key) };
56 let core = unsafe { ptr::read(&raw const self.core) };
58
59 mem::forget(self);
61
62 (inner, key, core)
63 }
64
65 #[doc = include_str!("../../doc/snippets/ref_counted_as_pin.md")]
66 #[must_use]
67 #[inline]
68 #[cfg_attr(test, mutants::skip)] pub fn as_pin(&self) -> Pin<&T> {
70 unsafe { Pin::new_unchecked(self) }
72 }
73
74 #[doc = include_str!("../../doc/snippets/ref_counted_as_pin_mut.md")]
75 #[must_use]
76 #[inline]
77 #[cfg_attr(test, mutants::skip)] pub fn as_pin_mut(&mut self) -> Pin<&mut T> {
79 let as_mut = unsafe { self.ptr().as_mut() };
82
83 unsafe { Pin::new_unchecked(as_mut) }
85 }
86
87 #[doc(hidden)]
97 #[must_use]
98 #[inline]
99 pub unsafe fn __private_cast_dyn_with_fn<U: ?Sized, F>(
100 self,
101 cast_fn: F,
102 ) -> LocalBlindPooledMut<U>
103 where
104 F: FnOnce(&mut T) -> &mut U,
105 {
106 let (inner, key, core) = self.into_parts();
107
108 let new_inner = unsafe { inner.__private_cast_dyn_with_fn(cast_fn) };
112
113 LocalBlindPooledMut {
114 inner: new_inner,
115 key,
116 core,
117 }
118 }
119}
120
121impl<T> LocalBlindPooledMut<T>
122where
123 T: Unpin,
124{
125 #[doc = include_str!("../../doc/snippets/ref_counted_into_inner.md")]
126 #[must_use]
127 #[inline]
128 #[cfg_attr(test, mutants::skip)] pub fn into_inner(self) -> T {
130 let (inner, key, core) = self.into_parts();
131
132 let mut core = RefCell::borrow_mut(&core);
133
134 let pool = core
135 .get_mut(&key)
136 .expect("if the handle still exists, the inner pool must still exist");
137
138 pool.remove_mut_unpin(inner)
139 }
140}
141
142impl<T: ?Sized> fmt::Debug for LocalBlindPooledMut<T> {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 f.debug_struct("LocalBlindPooledMut")
145 .field("inner", &self.inner)
146 .field("key", &self.key)
147 .field("core", &self.core)
148 .finish()
149 }
150}
151
152impl<T: ?Sized> Deref for LocalBlindPooledMut<T> {
153 type Target = T;
154
155 #[inline]
156 fn deref(&self) -> &Self::Target {
157 unsafe { self.ptr().as_ref() }
161 }
162}
163
164impl<T> DerefMut for LocalBlindPooledMut<T>
165where
166 T: ?Sized + Unpin,
167{
168 #[inline]
169 fn deref_mut(&mut self) -> &mut Self::Target {
170 unsafe { self.ptr().as_mut() }
174 }
175}
176
177impl<T: ?Sized> Borrow<T> for LocalBlindPooledMut<T> {
178 #[inline]
179 fn borrow(&self) -> &T {
180 self
181 }
182}
183
184impl<T> BorrowMut<T> for LocalBlindPooledMut<T>
185where
186 T: ?Sized + Unpin,
187{
188 #[inline]
189 fn borrow_mut(&mut self) -> &mut T {
190 self
191 }
192}
193
194impl<T: ?Sized> AsRef<T> for LocalBlindPooledMut<T> {
195 #[inline]
196 fn as_ref(&self) -> &T {
197 self
198 }
199}
200
201impl<T> AsMut<T> for LocalBlindPooledMut<T>
202where
203 T: ?Sized + Unpin,
204{
205 #[inline]
206 fn as_mut(&mut self) -> &mut T {
207 self
208 }
209}
210
211impl<T: ?Sized> Drop for LocalBlindPooledMut<T> {
212 fn drop(&mut self) {
213 let inner = unsafe { ptr::read(&raw const self.inner) };
221
222 let mut core = RefCell::borrow_mut(&self.core);
223
224 let pool = core
225 .get_mut(&self.key)
226 .expect("if the handle still exists, the inner pool must still exist");
227
228 pool.remove_mut(inner);
229 }
230}
231
232#[cfg(test)]
233mod tests {
234 use static_assertions::assert_not_impl_any;
235
236 use super::*;
237
238 assert_not_impl_any!(LocalBlindPooledMut<u32>: Send, Sync);
239
240 assert_not_impl_any!(RawPooledMut<()>: Drop);
242}