facet_reflect/poke/
value.rs1use crate::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 pub(crate) unsafe fn new(data: OpaqueUninit<'mem>, shape: &'static Shape) -> Self {
70 Self { data, shape }
71 }
72
73 #[inline(always)]
75 fn vtable(&self) -> &'static ValueVTable {
76 self.shape.vtable
77 }
78
79 pub unsafe fn data(&mut self) -> OpaqueUninit<'mem> {
85 self.data
86 }
87
88 pub fn try_from<'src>(
92 self,
93 source: OpaqueConst<'src>,
94 ) -> Result<Opaque<'mem>, (Self, TryFromError)> {
95 if let Some(try_from_fn) = self.vtable().try_from {
96 match unsafe { try_from_fn(source, self.data) } {
97 Ok(built_val) => Ok(built_val),
98 Err(err) => Err((self, err)),
99 }
100 } else {
101 let shape = self.shape;
102 Err((self, TryFromError::Unimplemented(shape)))
103 }
104 }
105
106 pub fn parse(self, s: &str) -> Result<Opaque<'mem>, Self> {
110 if let Some(parse_fn) = self.vtable().parse {
111 match unsafe { parse_fn(s, self.data) } {
112 Ok(parsed_val) => Ok(parsed_val),
113 Err(_) => Err(self),
114 }
115 } else {
116 Err(self)
117 }
118 }
119
120 pub fn put<'src, T>(self, value: T) -> Opaque<'mem>
126 where
127 T: Facet + 'src,
128 {
129 self.shape.assert_type::<T>();
130 unsafe { self.data.put(value) }
131 }
132
133 pub fn default_in_place(self) -> Result<Opaque<'mem>, Self> {
137 if let Some(default_in_place_fn) = self.vtable().default_in_place {
138 let default_val = unsafe { default_in_place_fn(self.data) };
139 Ok(default_val)
140 } else {
141 Err(self)
142 }
143 }
144
145 pub fn clone_from<'src>(self, source: Peek<'src>) -> Result<Peek<'mem>, Self> {
149 if let Some(clone_fn) = self.vtable().clone_into {
150 let cloned_val = unsafe { clone_fn(source.data(), self.data) };
151 Ok(unsafe { Peek::unchecked_new(cloned_val.as_const(), self.shape) })
153 } else {
154 Err(self)
155 }
156 }
157}
158
159pub struct TypedPokeValue<'mem, T: Facet> {
161 poke_value: PokeValue<'mem>,
162 _phantom: core::marker::PhantomData<T>,
163}
164
165impl<'mem, T: Facet> TypedPokeValue<'mem, T> {
166 fn new(poke_value: PokeValue<'mem>) -> Self {
168 Self {
169 poke_value,
170 _phantom: core::marker::PhantomData,
171 }
172 }
173
174 pub fn replace(self, value: T) -> Opaque<'mem> {
176 unsafe { self.poke_value.data.replace(value) }
178 }
179}
180
181pub struct PokeValue<'mem> {
183 data: Opaque<'mem>,
184 shape: &'static Shape,
185}
186
187impl core::fmt::Debug for PokeValue<'_> {
188 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
189 f.debug_struct("PokeValue")
190 .field("shape", &self.shape)
191 .field("data", &self.as_peek())
192 .finish()
193 }
194}
195
196impl<'mem> PokeValue<'mem> {
197 #[inline(always)]
198 pub fn into_value(self) -> Self {
200 self
201 }
202
203 pub fn typed<T: Facet>(self) -> Result<TypedPokeValue<'mem, T>, Self> {
207 if self.shape.is_type::<T>() {
208 Ok(TypedPokeValue::new(self))
209 } else {
210 Err(self)
211 }
212 }
213
214 #[inline(always)]
216 pub fn shape(&self) -> &'static Shape {
217 self.shape
218 }
219
220 pub(crate) unsafe fn new(data: Opaque<'mem>, shape: &'static Shape) -> Self {
226 Self { data, shape }
227 }
228
229 #[inline(always)]
231 fn vtable(&self) -> &'static ValueVTable {
232 self.shape.vtable
233 }
234
235 pub fn as_peek(&self) -> Peek<'_> {
237 unsafe { Peek::unchecked_new(self.data.as_const(), self.shape) }
238 }
239
240 pub unsafe fn data(&mut self) -> Opaque<'mem> {
246 self.data
247 }
248
249 pub fn replace<'src, T>(self, value: T) -> Opaque<'mem>
254 where
255 T: Facet + 'src,
256 {
257 self.shape.assert_type::<T>();
258 unsafe { self.data.replace(value) }
259 }
260
261 pub fn debug_fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
263 if let Some(debug_fn) = self.vtable().debug {
264 unsafe { debug_fn(self.data.as_const(), f) }
265 } else {
266 f.write_str("<no debug impl>")
267 }
268 }
269
270 pub fn display_fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
272 if let Some(display_fn) = self.vtable().display {
273 unsafe { display_fn(self.data.as_const(), f) }
274 } else {
275 f.write_str("<no display impl>")
276 }
277 }
278}