facet_reflect/partial/partial_api/
set.rs1use super::*;
2use facet_core::{Def, DynDateTimeKind, NumericType, PrimitiveType, Type};
3
4impl<'facet, const BORROW: bool> Partial<'facet, BORROW> {
8 pub fn set<U>(mut self, value: U) -> Result<Self, ReflectError>
14 where
15 U: Facet<'facet>,
16 {
17 struct DropVal<U> {
18 ptr: *mut U,
19 }
20 impl<U> Drop for DropVal<U> {
21 #[inline]
22 fn drop(&mut self) {
23 unsafe { core::ptr::drop_in_place(self.ptr) };
24 }
25 }
26
27 let mut value = ManuallyDrop::new(value);
28 let drop = DropVal {
29 ptr: (&mut value) as *mut ManuallyDrop<U> as *mut U,
30 };
31
32 let ptr_const = PtrConst::new(drop.ptr);
33 self = unsafe { self.set_shape(ptr_const, U::SHAPE)? };
35 core::mem::forget(drop);
36
37 Ok(self)
38 }
39
40 #[inline]
54 pub unsafe fn set_shape(
55 mut self,
56 src_value: PtrConst,
57 src_shape: &'static Shape,
58 ) -> Result<Self, ReflectError> {
59 let fr = self.frames_mut().last_mut().unwrap();
60 crate::trace!("set_shape({src_shape:?})");
61
62 if let Def::DynamicValue(dyn_def) = &fr.allocated.shape().def {
64 return unsafe { self.set_into_dynamic_value(src_value, src_shape, dyn_def) };
65 }
66
67 if !fr.allocated.shape().is_shape(src_shape) {
68 return Err(ReflectError::WrongShape {
69 expected: fr.allocated.shape(),
70 actual: src_shape,
71 });
72 }
73
74 fr.deinit_for_replace();
75
76 unsafe {
79 fr.data.copy_from(src_value, fr.allocated.shape()).unwrap();
82 }
83
84 unsafe {
86 fr.mark_as_init();
87 }
88
89 Ok(self)
90 }
91
92 unsafe fn set_into_dynamic_value(
98 mut self,
99 src_value: PtrConst,
100 src_shape: &'static Shape,
101 dyn_def: &facet_core::DynamicValueDef,
102 ) -> Result<Self, ReflectError> {
103 let fr = self.frames_mut().last_mut().unwrap();
104 let vtable = dyn_def.vtable;
105
106 fr.deinit_for_replace();
108
109 if fr.allocated.shape().is_shape(src_shape) {
111 unsafe {
112 fr.data.copy_from(src_value, fr.allocated.shape()).unwrap();
113 fr.mark_as_init();
114 }
115 return Ok(self);
116 }
117
118 let size_bits = src_shape
120 .layout
121 .sized_layout()
122 .map(|l| l.size() * 8)
123 .unwrap_or(0);
124
125 match &src_shape.ty {
127 Type::Primitive(PrimitiveType::Boolean) => {
128 let val = unsafe { *(src_value.as_byte_ptr() as *const bool) };
129 unsafe { (vtable.set_bool)(fr.data, val) };
130 }
131 Type::Primitive(PrimitiveType::Numeric(NumericType::Float)) => {
132 if size_bits == 64 {
133 let val = unsafe { *(src_value.as_byte_ptr() as *const f64) };
134 let success = unsafe { (vtable.set_f64)(fr.data, val) };
135 if !success {
136 return Err(ReflectError::OperationFailed {
137 shape: src_shape,
138 operation: "f64 value (NaN/Infinity) not representable in dynamic value",
139 });
140 }
141 } else if size_bits == 32 {
142 let val = unsafe { *(src_value.as_byte_ptr() as *const f32) } as f64;
143 let success = unsafe { (vtable.set_f64)(fr.data, val) };
144 if !success {
145 return Err(ReflectError::OperationFailed {
146 shape: src_shape,
147 operation: "f32 value (NaN/Infinity) not representable in dynamic value",
148 });
149 }
150 } else {
151 return Err(ReflectError::OperationFailed {
152 shape: src_shape,
153 operation: "unsupported float size for dynamic value",
154 });
155 }
156 }
157 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: true })) => {
158 let val: i64 = match size_bits {
159 8 => (unsafe { *(src_value.as_byte_ptr() as *const i8) }) as i64,
160 16 => (unsafe { *(src_value.as_byte_ptr() as *const i16) }) as i64,
161 32 => (unsafe { *(src_value.as_byte_ptr() as *const i32) }) as i64,
162 64 => unsafe { *(src_value.as_byte_ptr() as *const i64) },
163 _ => {
164 return Err(ReflectError::OperationFailed {
165 shape: src_shape,
166 operation: "unsupported signed integer size for dynamic value",
167 });
168 }
169 };
170 unsafe { (vtable.set_i64)(fr.data, val) };
171 }
172 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: false })) => {
173 let val: u64 = match size_bits {
174 8 => (unsafe { *src_value.as_byte_ptr() }) as u64,
175 16 => (unsafe { *(src_value.as_byte_ptr() as *const u16) }) as u64,
176 32 => (unsafe { *(src_value.as_byte_ptr() as *const u32) }) as u64,
177 64 => unsafe { *(src_value.as_byte_ptr() as *const u64) },
178 _ => {
179 return Err(ReflectError::OperationFailed {
180 shape: src_shape,
181 operation: "unsupported unsigned integer size for dynamic value",
182 });
183 }
184 };
185 unsafe { (vtable.set_u64)(fr.data, val) };
186 }
187 Type::Primitive(PrimitiveType::Textual(_)) => {
188 if src_shape.type_identifier == "char" {
190 let c = unsafe { *(src_value.as_byte_ptr() as *const char) };
191 let mut buf = [0u8; 4];
192 let s = c.encode_utf8(&mut buf);
193 unsafe { (vtable.set_str)(fr.data, s) };
194 } else {
195 let s: &str = unsafe { *(src_value.as_byte_ptr() as *const &str) };
197 unsafe { (vtable.set_str)(fr.data, s) };
198 }
199 }
200 _ => {
201 if let Some(set_bytes) = vtable.set_bytes
202 && let Def::List(list_def) = &src_shape.def
203 && list_def.t.is_type::<u8>()
204 {
205 let bytes: &::alloc::vec::Vec<u8> =
206 unsafe { &*(src_value.as_byte_ptr() as *const ::alloc::vec::Vec<u8>) };
207 unsafe { (set_bytes)(fr.data, bytes.as_slice()) };
208 unsafe {
210 src_shape
211 .call_drop_in_place(PtrMut::new(src_value.as_byte_ptr() as *mut u8));
212 }
213 let fr = self.frames_mut().last_mut().unwrap();
214 fr.tracker = Tracker::DynamicValue {
215 state: DynamicValueState::Scalar,
216 };
217 unsafe { fr.mark_as_init() };
218 return Ok(self);
219 }
220
221 if src_shape.type_identifier == "String" {
223 let s: &::alloc::string::String =
224 unsafe { &*(src_value.as_byte_ptr() as *const ::alloc::string::String) };
225 unsafe { (vtable.set_str)(fr.data, s.as_str()) };
226 unsafe {
228 src_shape
229 .call_drop_in_place(PtrMut::new(src_value.as_byte_ptr() as *mut u8));
230 }
231 } else {
232 return Err(ReflectError::OperationFailed {
233 shape: src_shape,
234 operation: "cannot convert this type to dynamic value",
235 });
236 }
237 }
238 }
239
240 let fr = self.frames_mut().last_mut().unwrap();
241 fr.tracker = Tracker::DynamicValue {
242 state: DynamicValueState::Scalar,
243 };
244 unsafe { fr.mark_as_init() };
245 Ok(self)
246 }
247
248 #[allow(clippy::too_many_arguments)]
253 pub fn set_datetime(
254 mut self,
255 year: i32,
256 month: u8,
257 day: u8,
258 hour: u8,
259 minute: u8,
260 second: u8,
261 nanos: u32,
262 kind: DynDateTimeKind,
263 ) -> Result<Self, ReflectError> {
264 let fr = self.frames_mut().last_mut().unwrap();
265
266 let dyn_def = match &fr.allocated.shape().def {
268 Def::DynamicValue(dv) => dv,
269 _ => {
270 return Err(ReflectError::OperationFailed {
271 shape: fr.allocated.shape(),
272 operation: "set_datetime requires a DynamicValue target",
273 });
274 }
275 };
276
277 let vtable = dyn_def.vtable;
278
279 let Some(set_datetime_fn) = vtable.set_datetime else {
281 return Err(ReflectError::OperationFailed {
282 shape: fr.allocated.shape(),
283 operation: "dynamic value type does not support datetime",
284 });
285 };
286
287 fr.deinit_for_replace();
288
289 unsafe {
291 set_datetime_fn(fr.data, year, month, day, hour, minute, second, nanos, kind);
292 }
293
294 let fr = self.frames_mut().last_mut().unwrap();
295 fr.tracker = Tracker::DynamicValue {
296 state: DynamicValueState::Scalar,
297 };
298 unsafe { fr.mark_as_init() };
299 Ok(self)
300 }
301
302 pub unsafe fn set_from_function<F>(mut self, f: F) -> Result<Self, ReflectError>
312 where
313 F: FnOnce(PtrUninit) -> Result<(), ReflectError>,
314 {
315 let frame = self.frames_mut().last_mut().unwrap();
316
317 frame.deinit_for_replace();
318 f(frame.data)?;
319
320 unsafe {
322 frame.mark_as_init();
323 }
324
325 Ok(self)
326 }
327
328 #[inline]
337 pub fn set_default(self) -> Result<Self, ReflectError> {
338 let frame = self.frames().last().unwrap();
339 let shape = frame.allocated.shape();
340
341 unsafe {
343 self.set_from_function(move |ptr| {
344 shape.call_default_in_place(ptr.assume_init()).ok_or(
345 ReflectError::OperationFailed {
346 shape,
347 operation: "type does not implement Default",
348 },
349 )?;
350 Ok(())
351 })
352 }
353 }
354
355 pub unsafe fn set_from_peek(self, peek: &Peek<'_, '_>) -> Result<Self, ReflectError> {
366 let src_ptr = peek.data();
368 let src_shape = peek.shape();
369
370 unsafe { self.set_shape(src_ptr, src_shape) }
372 }
373
374 pub fn parse_from_str(mut self, s: &str) -> Result<Self, ReflectError> {
378 let frame = self.frames_mut().last_mut().unwrap();
379 let shape = frame.allocated.shape();
380
381 frame.deinit_for_replace();
382
383 let result = unsafe { shape.call_parse(s, frame.data.assume_init()) };
385
386 match result {
387 Some(Ok(())) => {
388 unsafe {
390 frame.mark_as_init();
391 }
392 Ok(self)
393 }
394 Some(Err(_pe)) => {
395 Err(ReflectError::ParseFailed {
397 shape,
398 input: s.into(),
399 })
400 }
401 None => Err(ReflectError::OperationFailed {
402 shape,
403 operation: "Type does not support parsing from string",
404 }),
405 }
406 }
407
408 pub fn parse_from_bytes(mut self, bytes: &[u8]) -> Result<Self, ReflectError> {
415 let frame = self.frames_mut().last_mut().unwrap();
416 let shape = frame.allocated.shape();
417
418 frame.deinit_for_replace();
419
420 let result = unsafe { shape.call_parse_bytes(bytes, frame.data.assume_init()) };
422
423 match result {
424 Some(Ok(())) => {
425 unsafe {
427 frame.mark_as_init();
428 }
429 Ok(self)
430 }
431 Some(Err(_pe)) => {
432 Err(ReflectError::OperationFailed {
434 shape,
435 operation: "Failed to parse bytes value",
436 })
437 }
438 None => Err(ReflectError::OperationFailed {
439 shape,
440 operation: "Type does not support parsing from bytes",
441 }),
442 }
443 }
444}