facet_reflect/poke/
value.rs1use crate::{ScalarType, peek::Peek};
2use facet_core::{Facet, Opaque, OpaqueConst, OpaqueUninit, Shape, TryFromError, ValueVTable};
3
4pub struct TypedPokeValueUninit<'mem, T: Facet> {
6 poke_value: PokeValueUninit<'mem>,
7 _phantom: core::marker::PhantomData<T>,
8}
9
10impl<'mem, T: Facet> TypedPokeValueUninit<'mem, T> {
11 fn new(poke_value: PokeValueUninit<'mem>) -> Self {
13 Self {
14 poke_value,
15 _phantom: core::marker::PhantomData,
16 }
17 }
18
19 pub fn put(self, value: T) -> PokeValue<'mem> {
21 let data = unsafe { self.poke_value.data.put(value) };
23 unsafe { PokeValue::new(data, self.poke_value.shape) }
24 }
25}
26
27pub struct PokeValueUninit<'mem> {
29 data: OpaqueUninit<'mem>,
30 shape: &'static Shape,
31}
32
33impl core::fmt::Debug for PokeValueUninit<'_> {
34 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35 f.debug_struct("PokeValue")
36 .field("shape", &self.shape)
37 .finish_non_exhaustive()
38 }
39}
40
41impl<'mem> PokeValueUninit<'mem> {
42 #[inline(always)]
43 pub fn into_value(self) -> Self {
45 self
46 }
47
48 pub fn typed<T: Facet>(self) -> Result<TypedPokeValueUninit<'mem, T>, Self> {
52 if self.shape.is_type::<T>() {
53 Ok(TypedPokeValueUninit::new(self))
54 } else {
55 Err(self)
56 }
57 }
58
59 #[inline(always)]
61 pub fn shape(&self) -> &'static Shape {
62 self.shape
63 }
64
65 pub(crate) unsafe fn new(data: OpaqueUninit<'mem>, shape: &'static Shape) -> Self {
71 Self { data, shape }
72 }
73
74 #[inline(always)]
76 fn vtable(&self) -> &'static ValueVTable {
77 self.shape.vtable
78 }
79
80 pub unsafe fn data(&mut self) -> OpaqueUninit<'mem> {
86 self.data
87 }
88
89 pub fn try_from<'src>(
93 self,
94 source: OpaqueConst<'src>,
95 ) -> Result<Opaque<'mem>, (Self, TryFromError)> {
96 if let Some(try_from_fn) = self.vtable().try_from {
97 match unsafe { try_from_fn(source, self.data) } {
98 Ok(built_val) => Ok(built_val),
99 Err(err) => Err((self, err)),
100 }
101 } else {
102 let shape = self.shape;
103 Err((self, TryFromError::Unimplemented(shape)))
104 }
105 }
106
107 pub fn parse(self, s: &str) -> Result<Opaque<'mem>, Self> {
111 if let Some(parse_fn) = self.vtable().parse {
112 match unsafe { parse_fn(s, self.data) } {
113 Ok(parsed_val) => Ok(parsed_val),
114 Err(_) => Err(self),
115 }
116 } else {
117 Err(self)
118 }
119 }
120
121 pub fn put<'src, T>(self, value: T) -> Opaque<'mem>
127 where
128 T: Facet + 'src,
129 {
130 self.shape.assert_type::<T>();
131 unsafe { self.data.put(value) }
132 }
133
134 pub fn default_in_place(self) -> Result<Opaque<'mem>, Self> {
138 if let Some(default_in_place_fn) = self.vtable().default_in_place {
139 let default_val = unsafe { default_in_place_fn(self.data) };
140 Ok(default_val)
141 } else {
142 Err(self)
143 }
144 }
145
146 pub fn clone_from<'src>(self, source: Peek<'src>) -> Result<Peek<'mem>, Self> {
150 if let Some(clone_fn) = self.vtable().clone_into {
151 let cloned_val = unsafe { clone_fn(source.data(), self.data) };
152 Ok(unsafe { Peek::unchecked_new(cloned_val.as_const(), self.shape) })
154 } else {
155 Err(self)
156 }
157 }
158
159 pub fn scalar_type(&self) -> Option<ScalarType> {
161 ScalarType::try_from_shape(self.shape)
162 }
163}
164
165pub struct TypedPokeValue<'mem, T: Facet> {
167 poke_value: PokeValue<'mem>,
168 _phantom: core::marker::PhantomData<T>,
169}
170
171impl<'mem, T: Facet> TypedPokeValue<'mem, T> {
172 fn new(poke_value: PokeValue<'mem>) -> Self {
174 Self {
175 poke_value,
176 _phantom: core::marker::PhantomData,
177 }
178 }
179
180 pub fn replace(self, value: T) -> Opaque<'mem> {
182 unsafe { self.poke_value.data.replace(value) }
184 }
185}
186
187pub struct PokeValue<'mem> {
189 data: Opaque<'mem>,
190 shape: &'static Shape,
191}
192
193impl core::fmt::Debug for PokeValue<'_> {
194 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
195 f.debug_struct("PokeValue")
196 .field("shape", &self.shape)
197 .field("data", &self.as_peek())
198 .finish()
199 }
200}
201
202impl<'mem> PokeValue<'mem> {
203 pub unsafe fn unchecked_new(data: Opaque<'mem>, shape: &'static Shape) -> Self {
209 Self { data, shape }
210 }
211
212 #[inline(always)]
213 pub fn into_value(self) -> Self {
215 self
216 }
217
218 pub fn typed<T: Facet>(self) -> Result<TypedPokeValue<'mem, T>, Self> {
222 if self.shape.is_type::<T>() {
223 Ok(TypedPokeValue::new(self))
224 } else {
225 Err(self)
226 }
227 }
228
229 #[inline(always)]
231 pub fn shape(&self) -> &'static Shape {
232 self.shape
233 }
234
235 pub(crate) unsafe fn new(data: Opaque<'mem>, shape: &'static Shape) -> Self {
241 Self { data, shape }
242 }
243
244 #[inline(always)]
246 fn vtable(&self) -> &'static ValueVTable {
247 self.shape.vtable
248 }
249
250 pub fn as_peek(&self) -> Peek<'_> {
252 unsafe { Peek::unchecked_new(self.data.as_const(), self.shape) }
253 }
254
255 pub unsafe fn data(&mut self) -> Opaque<'mem> {
261 self.data
262 }
263
264 pub fn replace<'src, T>(self, value: T) -> Opaque<'mem>
269 where
270 T: Facet + 'src,
271 {
272 self.shape.assert_type::<T>();
273 unsafe { self.data.replace(value) }
274 }
275
276 pub fn debug_fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
278 if let Some(debug_fn) = self.vtable().debug {
279 unsafe { debug_fn(self.data.as_const(), f) }
280 } else {
281 f.write_str("<no debug impl>")
282 }
283 }
284
285 pub fn display_fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
287 if let Some(display_fn) = self.vtable().display {
288 unsafe { display_fn(self.data.as_const(), f) }
289 } else {
290 f.write_str("<no display impl>")
291 }
292 }
293
294 pub fn scalar_type(&self) -> Option<ScalarType> {
296 ScalarType::try_from_shape(self.shape)
297 }
298}