facet_reflect/poke/
smart_pointer.rs1use facet_core::{
2 Facet, LockResult, Opaque, OpaqueConst, OpaqueUninit, Shape, SmartPointerDef,
3 SmartPointerFlags, SmartPointerVTable,
4};
5
6use crate::PeekValue;
7
8pub struct PokeSmartPointerUninit<'mem> {
10 data: OpaqueUninit<'mem>,
11 shape: &'static Shape,
12 def: SmartPointerDef,
13}
14
15impl<'mem> PokeSmartPointerUninit<'mem> {
16 pub(crate) unsafe fn new(
22 data: OpaqueUninit<'mem>,
23 shape: &'static Shape,
24 def: SmartPointerDef,
25 ) -> Self {
26 Self { data, shape, def }
27 }
28
29 pub fn shape(&self) -> &'static Shape {
31 self.shape
32 }
33
34 pub fn def(&self) -> &SmartPointerDef {
36 &self.def
37 }
38
39 pub fn vtable(&self) -> &'static SmartPointerVTable {
41 self.def.vtable
42 }
43
44 #[inline(always)]
46 pub fn into_value(self) -> crate::PokeValueUninit<'mem> {
47 unsafe { crate::PokeValueUninit::new(self.data, self.shape) }
48 }
49
50 pub fn from_t<T>(self, value: T) -> Option<PokeSmartPointer<'mem>> {
55 let into_fn = self.def.vtable.new_into_fn?;
56
57 let value_opaque = OpaqueConst::new(&raw const value);
58 let opaque = unsafe { into_fn(self.data, value_opaque) };
59 core::mem::forget(value);
60 Some(PokeSmartPointer {
61 data: opaque,
62 shape: self.shape,
63 def: self.def,
64 })
65 }
66
67 pub fn from_peek_value(self, value: PeekValue<'mem>) -> Option<PokeSmartPointer<'mem>> {
75 assert_eq!(
77 value.shape(),
78 self.def.t,
79 "Inner value shape does not match expected smart pointer inner type"
80 );
81
82 let into_fn = self.def.vtable.new_into_fn?;
83
84 let opaque = unsafe { into_fn(self.data, value.data()) };
85 Some(PokeSmartPointer {
86 data: opaque,
87 shape: self.shape,
88 def: self.def,
89 })
90 }
91}
92
93pub struct PokeSmartPointer<'mem> {
94 data: Opaque<'mem>,
95 shape: &'static Shape,
96 def: SmartPointerDef,
97}
98
99impl<'mem> PokeSmartPointer<'mem> {
100 pub(crate) unsafe fn new(
106 data: Opaque<'mem>,
107 shape: &'static Shape,
108 def: SmartPointerDef,
109 ) -> Self {
110 Self { data, shape, def }
111 }
112
113 pub fn shape(&self) -> &'static Shape {
115 self.shape
116 }
117
118 pub fn def(&self) -> &SmartPointerDef {
120 &self.def
121 }
122
123 pub fn vtable(&self) -> &'static SmartPointerVTable {
125 self.def.vtable
126 }
127
128 pub fn is_weak(&self) -> bool {
130 self.def.flags.contains(SmartPointerFlags::WEAK)
131 }
132
133 pub fn is_atomic(&self) -> bool {
135 self.def.flags.contains(SmartPointerFlags::ATOMIC)
136 }
137
138 pub fn is_lock(&self) -> bool {
140 self.def.flags.contains(SmartPointerFlags::LOCK)
141 }
142
143 pub fn known_type(&self) -> Option<facet_core::KnownSmartPointer> {
145 self.def.known
146 }
147
148 pub fn inner_type(&self) -> &'static Shape {
150 self.def.t
151 }
152
153 pub fn try_borrow(&self) -> Option<PeekValue<'_>> {
155 let borrow_fn = self.def.vtable.borrow_fn?;
156 let opaque = unsafe { borrow_fn(self.data.as_const()) };
157 Some(unsafe { PeekValue::unchecked_new(opaque, self.def.t) })
158 }
159
160 pub fn try_upgrade(&self) -> Option<Self> {
162 let upgrade_fn = self.def.vtable.try_upgrade_fn?;
163 let opaque = unsafe { upgrade_fn(self.data)? };
164 Some(Self {
165 data: opaque,
166 shape: self.shape,
167 def: self.def,
168 })
169 }
170
171 pub fn try_lock(&self) -> Option<Result<PokeSmartPointerWriteGuard<'_>, ()>> {
173 let lock_fn = self.def.vtable.lock_fn?;
174 Some(unsafe {
175 lock_fn(self.data.as_const())
176 .map(|result| PokeSmartPointerWriteGuard::from_lock_result(result, self.def.t))
177 })
178 }
179
180 pub fn try_read(&self) -> Option<Result<PokeSmartPointerReadGuard<'_>, ()>> {
182 let read_fn = self.def.vtable.read_fn?;
183 Some(unsafe {
184 read_fn(self.data.as_const())
185 .map(|result| PokeSmartPointerReadGuard::from_lock_result(result, self.def.t))
186 })
187 }
188
189 pub fn try_write(&self) -> Option<Result<PokeSmartPointerWriteGuard<'_>, ()>> {
191 let write_fn = self.def.vtable.write_fn?;
192 Some(unsafe {
193 write_fn(self.data.as_const())
194 .map(|result| PokeSmartPointerWriteGuard::from_lock_result(result, self.def.t))
195 })
196 }
197
198 #[inline(always)]
200 pub fn into_value(self) -> crate::PokeValue<'mem> {
201 unsafe { crate::PokeValue::new(self.data, self.shape) }
202 }
203
204 pub fn build_in_place<U: Facet>(self) -> U {
208 self.shape.assert_type::<U>();
210 unsafe { self.data.read::<U>() }
211 }
212}
213
214pub struct PokeSmartPointerWriteGuard<'mem> {
215 #[allow(dead_code)]
216 lr: LockResult<'mem>,
217 shape: &'static Shape,
218}
219
220impl<'mem> PokeSmartPointerWriteGuard<'mem> {
221 pub(crate) unsafe fn from_lock_result(lr: LockResult<'mem>, shape: &'static Shape) -> Self {
223 Self { lr, shape }
224 }
225
226 pub fn shape(&self) -> &'static Shape {
228 self.shape
229 }
230}
231
232pub struct PokeSmartPointerReadGuard<'mem> {
233 #[allow(dead_code)]
234 lr: LockResult<'mem>,
235 shape: &'static Shape,
236}
237
238impl<'mem> PokeSmartPointerReadGuard<'mem> {
239 pub(crate) unsafe fn from_lock_result(lr: LockResult<'mem>, shape: &'static Shape) -> Self {
241 Self { lr, shape }
242 }
243
244 pub fn shape(&self) -> &'static Shape {
246 self.shape
247 }
248}