facet_reflect/partial/partial_api/
set.rs1use super::*;
2use facet_core::{Def, DynDateTimeKind, KnownPointer, NumericType, PrimitiveType, Type};
3
4impl<'facet, const BORROW: bool> Partial<'facet, BORROW> {
8 pub fn set_empty_shared_slice(mut self) -> Result<Self, ReflectError> {
12 let shape = self.frames().last().unwrap().allocated.shape();
13 let align = match shape.def {
14 Def::Pointer(ptr_def)
15 if matches!(ptr_def.known, Some(KnownPointer::SharedReference)) =>
16 {
17 let Some(pointee) = ptr_def.pointee() else {
18 return Err(self.err(ReflectErrorKind::OperationFailed {
19 shape,
20 operation: "shared reference pointer missing pointee shape",
21 }));
22 };
23 let Def::Slice(slice_def) = pointee.def else {
24 return Err(self.err(ReflectErrorKind::OperationFailed {
25 shape,
26 operation: "set_empty_shared_slice requires a slice pointee",
27 }));
28 };
29 slice_def
30 .t
31 .layout
32 .sized_layout()
33 .map_or(1, |l| l.align().max(1))
34 }
35 _ => {
36 return Err(self.err(ReflectErrorKind::OperationFailed {
37 shape,
38 operation: "set_empty_shared_slice requires a shared slice reference",
39 }));
40 }
41 };
42
43 let fr = self.frames_mut().last_mut().unwrap();
44 fr.deinit_for_replace();
45
46 let data_ptr = align as *const u8 as usize;
48 unsafe {
49 let dst = fr.data.as_mut_byte_ptr() as *mut [usize; 2];
50 core::ptr::write(dst, [data_ptr, 0]);
51 fr.mark_as_init();
52 }
53
54 Ok(self)
55 }
56
57 pub fn set<U>(mut self, value: U) -> Result<Self, ReflectError>
63 where
64 U: Facet<'facet>,
65 {
66 struct DropVal<U> {
67 ptr: *mut U,
68 }
69 impl<U> Drop for DropVal<U> {
70 #[inline]
71 fn drop(&mut self) {
72 unsafe { core::ptr::drop_in_place(self.ptr) };
73 }
74 }
75
76 let mut value = ManuallyDrop::new(value);
77 let drop = DropVal {
78 ptr: (&mut value) as *mut ManuallyDrop<U> as *mut U,
79 };
80
81 let ptr_const = PtrConst::new(drop.ptr);
82 self = unsafe { self.set_shape(ptr_const, U::SHAPE)? };
84 core::mem::forget(drop);
85
86 Ok(self)
87 }
88
89 #[inline]
103 pub unsafe fn set_shape(
104 mut self,
105 src_value: PtrConst,
106 src_shape: &'static Shape,
107 ) -> Result<Self, ReflectError> {
108 let shape = self.frames().last().unwrap().allocated.shape();
110 let fr = self.frames_mut().last_mut().unwrap();
111 crate::trace!("set_shape({src_shape:?})");
112
113 if let Def::DynamicValue(dyn_def) = &shape.def {
115 return unsafe { self.set_into_dynamic_value(src_value, src_shape, dyn_def) };
116 }
117
118 if !shape.is_shape(src_shape) {
119 return Err(self.err(ReflectErrorKind::WrongShape {
120 expected: shape,
121 actual: src_shape,
122 }));
123 }
124
125 fr.deinit_for_replace();
126
127 unsafe {
130 fr.data.copy_from(src_value, fr.allocated.shape()).unwrap();
133 }
134
135 unsafe {
137 fr.mark_as_init();
138 }
139
140 Ok(self)
141 }
142
143 unsafe fn set_into_dynamic_value(
149 mut self,
150 src_value: PtrConst,
151 src_shape: &'static Shape,
152 dyn_def: &facet_core::DynamicValueDef,
153 ) -> Result<Self, ReflectError> {
154 let fr = self.frames_mut().last_mut().unwrap();
155 let vtable = dyn_def.vtable;
156
157 fr.deinit_for_replace();
159
160 if fr.allocated.shape().is_shape(src_shape) {
162 unsafe {
163 fr.data.copy_from(src_value, fr.allocated.shape()).unwrap();
164 fr.mark_as_init();
165 }
166 return Ok(self);
167 }
168
169 let size_bits = src_shape
171 .layout
172 .sized_layout()
173 .map(|l| l.size() * 8)
174 .unwrap_or(0);
175
176 match &src_shape.ty {
178 Type::Primitive(PrimitiveType::Boolean) => {
179 let val = unsafe { *(src_value.as_byte_ptr() as *const bool) };
180 unsafe { (vtable.set_bool)(fr.data, val) };
181 }
182 Type::Primitive(PrimitiveType::Numeric(NumericType::Float)) => {
183 if size_bits == 64 {
184 let val = unsafe { *(src_value.as_byte_ptr() as *const f64) };
185 let success = unsafe { (vtable.set_f64)(fr.data, val) };
186 if !success {
187 return Err(self.err(ReflectErrorKind::OperationFailed {
188 shape: src_shape,
189 operation: "f64 value (NaN/Infinity) not representable in dynamic value",
190 }));
191 }
192 } else if size_bits == 32 {
193 let val = unsafe { *(src_value.as_byte_ptr() as *const f32) } as f64;
194 let success = unsafe { (vtable.set_f64)(fr.data, val) };
195 if !success {
196 return Err(self.err(ReflectErrorKind::OperationFailed {
197 shape: src_shape,
198 operation: "f32 value (NaN/Infinity) not representable in dynamic value",
199 }));
200 }
201 } else {
202 return Err(self.err(ReflectErrorKind::OperationFailed {
203 shape: src_shape,
204 operation: "unsupported float size for dynamic value",
205 }));
206 }
207 }
208 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: true })) => {
209 let val: i64 = match size_bits {
210 8 => (unsafe { *(src_value.as_byte_ptr() as *const i8) }) as i64,
211 16 => (unsafe { *(src_value.as_byte_ptr() as *const i16) }) as i64,
212 32 => (unsafe { *(src_value.as_byte_ptr() as *const i32) }) as i64,
213 64 => unsafe { *(src_value.as_byte_ptr() as *const i64) },
214 _ => {
215 return Err(self.err(ReflectErrorKind::OperationFailed {
216 shape: src_shape,
217 operation: "unsupported signed integer size for dynamic value",
218 }));
219 }
220 };
221 unsafe { (vtable.set_i64)(fr.data, val) };
222 }
223 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: false })) => {
224 let val: u64 = match size_bits {
225 8 => (unsafe { *src_value.as_byte_ptr() }) as u64,
226 16 => (unsafe { *(src_value.as_byte_ptr() as *const u16) }) as u64,
227 32 => (unsafe { *(src_value.as_byte_ptr() as *const u32) }) as u64,
228 64 => unsafe { *(src_value.as_byte_ptr() as *const u64) },
229 _ => {
230 return Err(self.err(ReflectErrorKind::OperationFailed {
231 shape: src_shape,
232 operation: "unsupported unsigned integer size for dynamic value",
233 }));
234 }
235 };
236 unsafe { (vtable.set_u64)(fr.data, val) };
237 }
238 Type::Primitive(PrimitiveType::Textual(_)) => {
239 if *src_shape == *char::SHAPE {
241 let c = unsafe { *(src_value.as_byte_ptr() as *const char) };
242 let mut buf = [0u8; 4];
243 let s = c.encode_utf8(&mut buf);
244 unsafe { (vtable.set_str)(fr.data, s) };
245 } else {
246 let s: &str = unsafe { *(src_value.as_byte_ptr() as *const &str) };
248 unsafe { (vtable.set_str)(fr.data, s) };
249 }
250 }
251 _ => {
252 if let Some(set_bytes) = vtable.set_bytes
253 && let Def::List(list_def) = &src_shape.def
254 && list_def.t.is_type::<u8>()
255 {
256 let bytes: &::alloc::vec::Vec<u8> =
257 unsafe { &*(src_value.as_byte_ptr() as *const ::alloc::vec::Vec<u8>) };
258 unsafe { (set_bytes)(fr.data, bytes.as_slice()) };
259 unsafe {
261 src_shape
262 .call_drop_in_place(PtrMut::new(src_value.as_byte_ptr() as *mut u8));
263 }
264 let fr = self.frames_mut().last_mut().unwrap();
265 fr.tracker = Tracker::DynamicValue {
266 state: DynamicValueState::Scalar,
267 };
268 unsafe { fr.mark_as_init() };
269 return Ok(self);
270 }
271
272 if *src_shape == *::alloc::string::String::SHAPE {
274 let s: &::alloc::string::String =
275 unsafe { &*(src_value.as_byte_ptr() as *const ::alloc::string::String) };
276 unsafe { (vtable.set_str)(fr.data, s.as_str()) };
277 unsafe {
279 src_shape
280 .call_drop_in_place(PtrMut::new(src_value.as_byte_ptr() as *mut u8));
281 }
282 } else {
283 return Err(self.err(ReflectErrorKind::OperationFailed {
284 shape: src_shape,
285 operation: "cannot convert this type to dynamic value",
286 }));
287 }
288 }
289 }
290
291 let fr = self.frames_mut().last_mut().unwrap();
292 fr.tracker = Tracker::DynamicValue {
293 state: DynamicValueState::Scalar,
294 };
295 unsafe { fr.mark_as_init() };
296 Ok(self)
297 }
298
299 #[allow(clippy::too_many_arguments)]
304 pub fn set_datetime(
305 mut self,
306 year: i32,
307 month: u8,
308 day: u8,
309 hour: u8,
310 minute: u8,
311 second: u8,
312 nanos: u32,
313 kind: DynDateTimeKind,
314 ) -> Result<Self, ReflectError> {
315 let shape = self.frames().last().unwrap().allocated.shape();
317 let fr = self.frames_mut().last_mut().unwrap();
318
319 let dyn_def = match &shape.def {
321 Def::DynamicValue(dv) => dv,
322 _ => {
323 return Err(self.err(ReflectErrorKind::OperationFailed {
324 shape,
325 operation: "set_datetime requires a DynamicValue target",
326 }));
327 }
328 };
329
330 let vtable = dyn_def.vtable;
331
332 let Some(set_datetime_fn) = vtable.set_datetime else {
334 return Err(self.err(ReflectErrorKind::OperationFailed {
335 shape,
336 operation: "dynamic value type does not support datetime",
337 }));
338 };
339
340 fr.deinit_for_replace();
341
342 unsafe {
344 set_datetime_fn(fr.data, year, month, day, hour, minute, second, nanos, kind);
345 }
346
347 let fr = self.frames_mut().last_mut().unwrap();
348 fr.tracker = Tracker::DynamicValue {
349 state: DynamicValueState::Scalar,
350 };
351 unsafe { fr.mark_as_init() };
352 Ok(self)
353 }
354
355 pub unsafe fn set_from_function<F>(mut self, f: F) -> Result<Self, ReflectError>
365 where
366 F: FnOnce(PtrUninit) -> Result<(), ReflectErrorKind>,
367 {
368 let frame = self.frames_mut().last_mut().unwrap();
369
370 frame.deinit_for_replace();
371 if let Err(kind) = f(frame.data) {
372 return Err(self.err(kind));
374 }
375
376 unsafe {
378 frame.mark_as_init();
379 }
380
381 Ok(self)
382 }
383
384 #[inline]
393 pub fn set_default(self) -> Result<Self, ReflectError> {
394 let frame = self.frames().last().unwrap();
395 let shape = frame.allocated.shape();
396
397 unsafe {
399 self.set_from_function(move |ptr| {
400 shape
401 .call_default_in_place(ptr)
402 .ok_or(ReflectErrorKind::OperationFailed {
403 shape,
404 operation: "type does not implement Default",
405 })
406 })
407 }
408 }
409
410 pub unsafe fn set_from_peek(self, peek: &Peek<'_, '_>) -> Result<Self, ReflectError> {
421 let src_ptr = peek.data();
423 let src_shape = peek.shape();
424
425 unsafe { self.set_shape(src_ptr, src_shape) }
427 }
428
429 pub fn parse_from_str(mut self, s: &str) -> Result<Self, ReflectError> {
433 let frame = self.frames_mut().last_mut().unwrap();
434 let shape = frame.allocated.shape();
435
436 frame.deinit_for_replace();
437
438 let result = unsafe { shape.call_parse(s, frame.data) };
440
441 match result {
442 Some(Ok(())) => {
443 unsafe {
445 frame.mark_as_init();
446 }
447 Ok(self)
448 }
449 Some(Err(_pe)) => {
450 Err(self.err(ReflectErrorKind::ParseFailed {
452 shape,
453 input: s.into(),
454 }))
455 }
456 None => Err(self.err(ReflectErrorKind::OperationFailed {
457 shape,
458 operation: "Type does not support parsing from string",
459 })),
460 }
461 }
462
463 pub fn parse_from_bytes(mut self, bytes: &[u8]) -> Result<Self, ReflectError> {
470 let frame = self.frames_mut().last_mut().unwrap();
471 let shape = frame.allocated.shape();
472
473 frame.deinit_for_replace();
474
475 let result = unsafe { shape.call_parse_bytes(bytes, frame.data) };
477
478 match result {
479 Some(Ok(())) => {
480 unsafe {
482 frame.mark_as_init();
483 }
484 Ok(self)
485 }
486 Some(Err(_pe)) => {
487 Err(self.err(ReflectErrorKind::OperationFailed {
489 shape,
490 operation: "Failed to parse bytes value",
491 }))
492 }
493 None => Err(self.err(ReflectErrorKind::OperationFailed {
494 shape,
495 operation: "Type does not support parsing from bytes",
496 })),
497 }
498 }
499}