infinity_pool/handles/
local.rs1use std::borrow::Borrow;
2use std::cell::RefCell;
3use std::fmt;
4use std::ops::Deref;
5use std::pin::Pin;
6use std::ptr::NonNull;
7use std::rc::Rc;
8
9use crate::{LocalPooledMut, RawOpaquePool, RawPooled, RawPooledMut};
10
11#[doc = include_str!("../../doc/snippets/ref_counted_handle_implications.md")]
13#[doc = include_str!("../../doc/snippets/shared_handle_implications.md")]
14pub struct LocalPooled<T: ?Sized> {
19 inner: RawPooled<T>,
20 remover: Rc<Remover>,
21}
22
23impl<T: ?Sized> LocalPooled<T> {
24 #[must_use]
25 pub(crate) fn new(inner: RawPooledMut<T>, pool: Rc<RefCell<RawOpaquePool>>) -> Self {
26 let inner = inner.into_shared();
27
28 let remover = Remover {
29 handle: inner.erase(),
30 pool,
31 };
32
33 Self {
34 inner,
35 remover: Rc::new(remover),
36 }
37 }
38
39 #[doc = include_str!("../../doc/snippets/handle_ptr.md")]
40 #[must_use]
41 #[inline]
42 pub fn ptr(&self) -> NonNull<T> {
43 self.inner.ptr()
44 }
45
46 #[doc = include_str!("../../doc/snippets/handle_erase.md")]
47 #[must_use]
48 #[inline]
49 pub fn erase(self) -> LocalPooled<()> {
50 LocalPooled {
51 inner: self.inner.erase(),
52 remover: self.remover,
53 }
54 }
55
56 #[doc = include_str!("../../doc/snippets/ref_counted_as_pin.md")]
57 #[must_use]
58 #[inline]
59 pub fn as_pin(&self) -> Pin<&T> {
60 unsafe { Pin::new_unchecked(self) }
62 }
63
64 #[doc(hidden)]
74 #[must_use]
75 #[inline]
76 pub unsafe fn __private_cast_dyn_with_fn<U: ?Sized, F>(self, cast_fn: F) -> LocalPooled<U>
77 where
78 F: FnOnce(&T) -> &U,
79 {
80 let new_inner = unsafe { self.inner.__private_cast_dyn_with_fn(cast_fn) };
84
85 LocalPooled {
86 inner: new_inner,
87 remover: self.remover,
88 }
89 }
90}
91
92impl<T: ?Sized> fmt::Debug for LocalPooled<T> {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 f.debug_struct("LocalPooled")
95 .field("inner", &self.inner)
96 .field("remover", &self.remover)
97 .finish()
98 }
99}
100
101impl<T: ?Sized> Deref for LocalPooled<T> {
102 type Target = T;
103
104 #[inline]
105 fn deref(&self) -> &Self::Target {
106 unsafe { self.ptr().as_ref() }
110 }
111}
112
113impl<T: ?Sized> Borrow<T> for LocalPooled<T> {
114 #[inline]
115 fn borrow(&self) -> &T {
116 self
117 }
118}
119
120impl<T: ?Sized> AsRef<T> for LocalPooled<T> {
121 #[inline]
122 fn as_ref(&self) -> &T {
123 self
124 }
125}
126
127impl<T: ?Sized> Clone for LocalPooled<T> {
128 #[inline]
129 fn clone(&self) -> Self {
130 Self {
131 inner: self.inner,
132 remover: Rc::clone(&self.remover),
133 }
134 }
135}
136
137impl<T: ?Sized> From<LocalPooledMut<T>> for LocalPooled<T> {
138 #[inline]
139 fn from(value: LocalPooledMut<T>) -> Self {
140 value.into_shared()
141 }
142}
143
144#[derive(Debug)]
146struct Remover {
147 handle: RawPooled<()>,
148 pool: Rc<RefCell<RawOpaquePool>>,
149}
150
151impl Drop for Remover {
152 fn drop(&mut self) {
153 let mut pool = self.pool.borrow_mut();
154
155 unsafe {
158 pool.remove(self.handle);
159 }
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use static_assertions::assert_not_impl_any;
166
167 use super::*;
168
169 assert_not_impl_any!(LocalPooled<u32>: Send, Sync);
170}