1use alloc::{
4 boxed::Box,
5 format,
6 string::{String, ToString},
7 vec::Vec,
8};
9
10use core::{marker::PhantomData, mem::ManuallyDrop, ptr::NonNull};
11
12use crate::{
13 Guard, HeapValue, Partial, Peek, ReflectError, TypedPartial,
14 partial::{Frame, FrameOwnership, MapInsertState, PartialState, Tracker, iset::ISet},
15 trace,
16};
17use facet_core::{
18 ArrayType, Characteristic, Def, EnumRepr, EnumType, Facet, Field, FieldAttribute, KnownPointer,
19 PtrConst, PtrMut, PtrUninit, SequenceType, Shape, StructType, Type, UserType, Variant,
20};
21
22impl<'facet> Partial<'facet> {
26 pub fn alloc<T>() -> Result<TypedPartial<'facet, T>, ReflectError>
28 where
29 T: Facet<'facet> + ?Sized,
30 {
31 Ok(TypedPartial {
32 inner: Self::alloc_shape(T::SHAPE)?,
33 phantom: PhantomData,
34 })
35 }
36
37 pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
39 crate::trace!(
40 "alloc_shape({:?}), with layout {:?}",
41 shape,
42 shape.layout.sized_layout()
43 );
44
45 let data = shape.allocate().map_err(|_| ReflectError::Unsized {
46 shape,
47 operation: "alloc_shape",
48 })?;
49
50 let mut frames = Vec::with_capacity(4);
54 frames.push(Frame::new(data, shape, FrameOwnership::Owned));
55
56 Ok(Self {
57 frames,
58 state: PartialState::Active,
59 invariant: PhantomData,
60 })
61 }
62}
63
64impl<'facet> Partial<'facet> {
68 #[inline]
77 pub fn frame_count(&self) -> usize {
78 self.frames.len()
79 }
80
81 #[inline]
83 pub fn shape(&self) -> &'static Shape {
84 self.frames
85 .last()
86 .expect("Partial always has at least one frame")
87 .shape
88 }
89
90 pub fn end(&mut self) -> Result<&mut Self, ReflectError> {
92 crate::trace!("end() called");
93 self.require_active()?;
94
95 if self.frames.len() == 1 {
97 if let Tracker::SmartPointerSlice {
98 vtable,
99 building_item,
100 } = &self.frames[0].tracker
101 {
102 if *building_item {
103 return Err(ReflectError::OperationFailed {
104 shape: self.frames[0].shape,
105 operation: "still building an item, finish it first",
106 });
107 }
108
109 let builder_ptr = unsafe { self.frames[0].data.assume_init() };
111 let arc_ptr = unsafe { (vtable.convert_fn)(builder_ptr) };
112
113 self.frames[0].data = PtrUninit::new(unsafe {
115 NonNull::new_unchecked(arc_ptr.as_byte_ptr() as *mut u8)
116 });
117 self.frames[0].tracker = Tracker::Init;
118 self.frames[0].ownership = FrameOwnership::ManagedElsewhere;
120
121 return Ok(self);
122 }
123 }
124
125 if self.frames.len() <= 1 {
126 return Err(ReflectError::InvariantViolation {
128 invariant: "Partial::end() called with only one frame on the stack",
129 });
130 }
131
132 {
134 let frame = self.frames.last().unwrap();
135 trace!(
136 "end(): Checking full initialization for frame with shape {} and tracker {:?}",
137 frame.shape,
138 frame.tracker.kind()
139 );
140 frame.require_full_initialization()?
141 }
142
143 let mut popped_frame = self.frames.pop().unwrap();
145
146 if popped_frame.using_custom_deserialization {
148 if let Some(deserialize_with) = self
149 .parent_field()
150 .and_then(|field| field.vtable.deserialize_with)
151 {
152 let parent_frame = self.frames.last_mut().unwrap();
153
154 trace!(
155 "Detected custom conversion needed from {} to {}",
156 popped_frame.shape, parent_frame.shape
157 );
158
159 unsafe {
160 let res = {
161 let inner_value_ptr = popped_frame.data.assume_init().as_const();
162 (deserialize_with)(inner_value_ptr, parent_frame.data)
163 };
164 let popped_frame_shape = popped_frame.shape;
165
166 popped_frame.deinit();
168 popped_frame.dealloc();
169 let rptr = res.map_err(|message| ReflectError::CustomDeserializationError {
170 message,
171 src_shape: popped_frame_shape,
172 dst_shape: parent_frame.shape,
173 })?;
174 if rptr.as_uninit() != parent_frame.data {
175 return Err(ReflectError::CustomDeserializationError {
176 message: "deserialize_with did not return the expected pointer".into(),
177 src_shape: popped_frame_shape,
178 dst_shape: parent_frame.shape,
179 });
180 }
181 parent_frame.mark_as_init();
182 }
183 return Ok(self);
184 }
185 }
186
187 let parent_frame = self.frames.last_mut().unwrap();
189
190 trace!(
191 "end(): Popped {} (tracker {:?}), Parent {} (tracker {:?})",
192 popped_frame.shape,
193 popped_frame.tracker.kind(),
194 parent_frame.shape,
195 parent_frame.tracker.kind()
196 );
197
198 let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
203 && parent_frame.shape.inner.is_some()
204 && parent_frame.shape.inner.unwrap() == popped_frame.shape
205 && parent_frame.shape.vtable.try_from.is_some();
206
207 if needs_conversion {
208 trace!(
209 "Detected implicit conversion needed from {} to {}",
210 popped_frame.shape, parent_frame.shape
211 );
212 if let Some(try_from_fn) = parent_frame.shape.vtable.try_from {
214 let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
215 let inner_shape = popped_frame.shape;
216
217 trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
218 let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
219
220 if let Err(e) = result {
221 trace!("Conversion failed: {e:?}");
222
223 if let FrameOwnership::Owned = popped_frame.ownership {
225 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
226 if layout.size() > 0 {
227 trace!(
228 "Deallocating conversion frame memory after failure: size={}, align={}",
229 layout.size(),
230 layout.align()
231 );
232 unsafe {
233 alloc::alloc::dealloc(
234 popped_frame.data.as_mut_byte_ptr(),
235 layout,
236 );
237 }
238 }
239 }
240 }
241
242 return Err(ReflectError::TryFromError {
243 src_shape: inner_shape,
244 dst_shape: parent_frame.shape,
245 inner: e,
246 });
247 }
248
249 trace!("Conversion succeeded, marking parent as initialized");
250 parent_frame.tracker = Tracker::Init;
251
252 if let FrameOwnership::Owned = popped_frame.ownership {
254 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
255 if layout.size() > 0 {
256 trace!(
257 "Deallocating conversion frame memory: size={}, align={}",
258 layout.size(),
259 layout.align()
260 );
261 unsafe {
262 alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
263 }
264 }
265 }
266 }
267
268 return Ok(self);
269 }
270 }
271
272 match &mut parent_frame.tracker {
273 Tracker::Struct {
274 iset,
275 current_child,
276 } => {
277 if let Some(idx) = *current_child {
278 iset.set(idx);
279 *current_child = None;
280 }
281 }
282 Tracker::Array {
283 iset,
284 current_child,
285 } => {
286 if let Some(idx) = *current_child {
287 iset.set(idx);
288 *current_child = None;
289 }
290 }
291 Tracker::SmartPointer { is_initialized } => {
292 if let Def::Pointer(smart_ptr_def) = parent_frame.shape.def {
294 let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn else {
295 return Err(ReflectError::OperationFailed {
296 shape: parent_frame.shape,
297 operation: "SmartPointer missing new_into_fn",
298 });
299 };
300
301 let inner_ptr = PtrMut::new(unsafe {
303 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
304 });
305
306 unsafe {
308 new_into_fn(parent_frame.data, inner_ptr);
309 }
310
311 popped_frame.tracker = Tracker::Uninit;
313
314 popped_frame.dealloc();
316
317 *is_initialized = true;
318 }
319 }
320 Tracker::Enum {
321 data,
322 current_child,
323 ..
324 } => {
325 if let Some(idx) = *current_child {
326 data.set(idx);
327 *current_child = None;
328 }
329 }
330 Tracker::List {
331 is_initialized: true,
332 current_child,
333 } => {
334 if *current_child {
335 if let Def::List(list_def) = parent_frame.shape.def {
337 let Some(push_fn) = list_def.vtable.push else {
338 return Err(ReflectError::OperationFailed {
339 shape: parent_frame.shape,
340 operation: "List missing push function",
341 });
342 };
343
344 let element_ptr = PtrMut::new(unsafe {
346 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
347 });
348
349 unsafe {
351 push_fn(
352 PtrMut::new(NonNull::new_unchecked(
353 parent_frame.data.as_mut_byte_ptr(),
354 )),
355 element_ptr,
356 );
357 }
358
359 popped_frame.tracker = Tracker::Uninit;
361 popped_frame.dealloc();
362
363 *current_child = false;
364 }
365 }
366 }
367 Tracker::Map {
368 is_initialized: true,
369 insert_state,
370 } => {
371 match insert_state {
372 MapInsertState::PushingKey { key_ptr } => {
373 if let Some(key_ptr) = key_ptr {
375 *insert_state = MapInsertState::PushingValue {
377 key_ptr: *key_ptr,
378 value_ptr: None,
379 };
380 }
381 }
382 MapInsertState::PushingValue { key_ptr, value_ptr } => {
383 if let (Some(value_ptr), Def::Map(map_def)) =
385 (value_ptr, parent_frame.shape.def)
386 {
387 let insert_fn = map_def.vtable.insert_fn;
388
389 unsafe {
391 insert_fn(
392 PtrMut::new(NonNull::new_unchecked(
393 parent_frame.data.as_mut_byte_ptr(),
394 )),
395 PtrMut::new(NonNull::new_unchecked(key_ptr.as_mut_byte_ptr())),
396 PtrMut::new(NonNull::new_unchecked(
397 value_ptr.as_mut_byte_ptr(),
398 )),
399 );
400 }
401
402 if let Ok(key_shape) = map_def.k().layout.sized_layout() {
408 if key_shape.size() > 0 {
409 unsafe {
410 alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
411 }
412 }
413 }
414 if let Ok(value_shape) = map_def.v().layout.sized_layout() {
415 if value_shape.size() > 0 {
416 unsafe {
417 alloc::alloc::dealloc(
418 value_ptr.as_mut_byte_ptr(),
419 value_shape,
420 );
421 }
422 }
423 }
424
425 *insert_state = MapInsertState::Idle;
427 }
428 }
429 MapInsertState::Idle => {
430 }
432 }
433 }
434 Tracker::Option { building_inner } => {
435 if *building_inner {
437 if let Def::Option(option_def) = parent_frame.shape.def {
438 let init_some_fn = option_def.vtable.init_some_fn;
440
441 let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
443
444 unsafe {
446 init_some_fn(parent_frame.data, inner_value_ptr);
447 }
448
449 if let FrameOwnership::Owned = popped_frame.ownership {
451 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
452 if layout.size() > 0 {
453 unsafe {
454 alloc::alloc::dealloc(
455 popped_frame.data.as_mut_byte_ptr(),
456 layout,
457 );
458 }
459 }
460 }
461 }
462
463 *building_inner = false;
465 } else {
466 return Err(ReflectError::OperationFailed {
467 shape: parent_frame.shape,
468 operation: "Option frame without Option definition",
469 });
470 }
471 }
472 }
473 Tracker::Uninit | Tracker::Init => {
474 match &parent_frame.shape.def {
477 Def::Pointer(smart_ptr_def) => {
478 let pointee =
479 smart_ptr_def
480 .pointee()
481 .ok_or(ReflectError::InvariantViolation {
482 invariant: "pointer type doesn't have a pointee",
483 })?;
484
485 if !pointee.is_shape(str::SHAPE) {
486 return Err(ReflectError::InvariantViolation {
487 invariant: "only T=str is supported when building SmartPointer<T> and T is unsized",
488 });
489 }
490
491 if !popped_frame.shape.is_shape(String::SHAPE) {
492 return Err(ReflectError::InvariantViolation {
493 invariant: "the popped frame should be String when building a SmartPointer<T>",
494 });
495 }
496
497 popped_frame.require_full_initialization()?;
498
499 use alloc::{rc::Rc, string::String, sync::Arc};
504 let parent_shape = parent_frame.shape;
505
506 let Some(known) = smart_ptr_def.known else {
507 return Err(ReflectError::OperationFailed {
508 shape: parent_shape,
509 operation: "SmartPointerStr for unknown smart pointer kind",
510 });
511 };
512
513 parent_frame.deinit();
514
515 let string_ptr = popped_frame.data.as_mut_byte_ptr() as *mut String;
517 let string_value = unsafe { core::ptr::read(string_ptr) };
518
519 match known {
520 KnownPointer::Box => {
521 let boxed: Box<str> = string_value.into_boxed_str();
522 unsafe {
523 core::ptr::write(
524 parent_frame.data.as_mut_byte_ptr() as *mut Box<str>,
525 boxed,
526 );
527 }
528 }
529 KnownPointer::Arc => {
530 let arc: Arc<str> = Arc::from(string_value.into_boxed_str());
531 unsafe {
532 core::ptr::write(
533 parent_frame.data.as_mut_byte_ptr() as *mut Arc<str>,
534 arc,
535 );
536 }
537 }
538 KnownPointer::Rc => {
539 let rc: Rc<str> = Rc::from(string_value.into_boxed_str());
540 unsafe {
541 core::ptr::write(
542 parent_frame.data.as_mut_byte_ptr() as *mut Rc<str>,
543 rc,
544 );
545 }
546 }
547 _ => {
548 return Err(ReflectError::OperationFailed {
549 shape: parent_shape,
550 operation: "Don't know how to build this pointer type",
551 });
552 }
553 }
554
555 parent_frame.tracker = Tracker::Init;
556
557 popped_frame.tracker = Tracker::Uninit;
558 popped_frame.dealloc();
559 }
560 _ => {
561 unreachable!(
562 "we popped a frame and parent was Init or Uninit, but it wasn't a smart pointer and... there's no way this should happen normally"
563 )
564 }
565 }
566 }
567 Tracker::SmartPointerSlice {
568 vtable,
569 building_item,
570 } => {
571 if *building_item {
572 let element_ptr = PtrMut::new(unsafe {
574 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
575 });
576
577 crate::trace!("Pushing element to slice builder");
579 unsafe {
580 let parent_ptr = parent_frame.data.assume_init();
581 (vtable.push_fn)(parent_ptr, element_ptr);
582 }
583
584 popped_frame.tracker = Tracker::Uninit;
585 popped_frame.dealloc();
586
587 if let Tracker::SmartPointerSlice {
588 building_item: bi, ..
589 } = &mut parent_frame.tracker
590 {
591 *bi = false;
592 }
593 }
594 }
595 _ => {}
596 }
597
598 Ok(self)
599 }
600
601 pub fn path(&self) -> String {
604 let mut out = String::new();
605
606 let mut path_components = Vec::new();
607 for (i, frame) in self.frames.iter().enumerate() {
610 match frame.shape.ty {
611 Type::User(user_type) => match user_type {
612 UserType::Struct(struct_type) => {
613 let mut field_str = None;
615 if let Tracker::Struct {
616 current_child: Some(idx),
617 ..
618 } = &frame.tracker
619 {
620 if let Some(field) = struct_type.fields.get(*idx) {
621 field_str = Some(field.name);
622 }
623 }
624 if i == 0 {
625 path_components.push(format!("{}", frame.shape));
627 }
628 if let Some(field_name) = field_str {
629 path_components.push(format!(".{field_name}"));
630 }
631 }
632 UserType::Enum(_enum_type) => {
633 if let Tracker::Enum {
635 variant,
636 current_child,
637 ..
638 } = &frame.tracker
639 {
640 if i == 0 {
641 path_components.push(format!("{}", frame.shape));
643 }
644 path_components.push(format!("::{}", variant.name));
645 if let Some(idx) = *current_child {
646 if let Some(field) = variant.data.fields.get(idx) {
647 path_components.push(format!(".{}", field.name));
648 }
649 }
650 } else if i == 0 {
651 path_components.push(format!("{}", frame.shape));
653 }
654 }
655 UserType::Union(_union_type) => {
656 path_components.push(format!("{}", frame.shape));
657 }
658 UserType::Opaque => {
659 path_components.push("<opaque>".to_string());
660 }
661 },
662 Type::Sequence(seq_type) => match seq_type {
663 facet_core::SequenceType::Array(_array_def) => {
664 if let Tracker::Array {
666 current_child: Some(idx),
667 ..
668 } = &frame.tracker
669 {
670 path_components.push(format!("[{idx}]"));
671 }
672 }
673 _ => {
675 path_components.push("[]".to_string());
677 }
678 },
679 Type::Pointer(_) => {
680 path_components.push("*".to_string());
682 }
683 _ => {
684 }
686 }
687 }
688 for component in path_components {
690 out.push_str(&component);
691 }
692 out
693 }
694
695 pub fn parent_field(&self) -> Option<&Field> {
697 self.frames.iter().rev().nth(1).and_then(|f| f.get_field())
698 }
699}
700
701impl<'facet> Partial<'facet> {
705 pub fn build(&mut self) -> Result<HeapValue<'facet>, ReflectError> {
707 self.require_active()?;
708 if self.frames.len() != 1 {
709 self.state = PartialState::BuildFailed;
710 return Err(ReflectError::InvariantViolation {
711 invariant: "Partial::build() expects a single frame — call end() until that's the case",
712 });
713 }
714
715 let frame = self.frames.pop().unwrap();
716
717 if let Err(e) = frame.require_full_initialization() {
719 self.frames.push(frame);
721 self.state = PartialState::BuildFailed;
722 return Err(e);
723 }
724
725 if let Some(invariants_fn) = frame.shape.vtable.invariants {
727 let value_ptr = unsafe { frame.data.assume_init().as_const() };
729 let invariants_ok = unsafe { invariants_fn(value_ptr) };
730
731 if !invariants_ok {
732 self.frames.push(frame);
734 self.state = PartialState::BuildFailed;
735 return Err(ReflectError::InvariantViolation {
736 invariant: "Type invariants check failed",
737 });
738 }
739 }
740
741 self.state = PartialState::Built;
743
744 match frame
745 .shape
746 .layout
747 .sized_layout()
748 .map_err(|_layout_err| ReflectError::Unsized {
749 shape: frame.shape,
750 operation: "build (final check for sized layout)",
751 }) {
752 Ok(layout) => Ok(HeapValue {
753 guard: Some(Guard {
754 ptr: unsafe { NonNull::new_unchecked(frame.data.as_mut_byte_ptr()) },
755 layout,
756 }),
757 shape: frame.shape,
758 phantom: PhantomData,
759 }),
760 Err(e) => {
761 self.frames.push(frame);
763 self.state = PartialState::BuildFailed;
764 Err(e)
765 }
766 }
767 }
768}
769
770impl<'facet> Partial<'facet> {
774 pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
780 where
781 U: Facet<'facet>,
782 {
783 self.require_active()?;
784 struct DropVal<U> {
785 ptr: *mut U,
786 }
787 impl<U> Drop for DropVal<U> {
788 #[inline]
789 fn drop(&mut self) {
790 unsafe { core::ptr::drop_in_place(self.ptr) };
791 }
792 }
793
794 let mut value = ManuallyDrop::new(value);
795 let drop = DropVal {
796 ptr: (&mut value) as *mut ManuallyDrop<U> as *mut U,
797 };
798
799 let ptr_const = PtrConst::new(unsafe { NonNull::new_unchecked(drop.ptr) });
800 unsafe {
801 self.set_shape(ptr_const, U::SHAPE)?
803 };
804 core::mem::forget(drop);
805
806 Ok(self)
807 }
808
809 #[inline]
823 pub unsafe fn set_shape(
824 &mut self,
825 src_value: PtrConst<'_>,
826 src_shape: &'static Shape,
827 ) -> Result<&mut Self, ReflectError> {
828 self.require_active()?;
829
830 let fr = self.frames.last_mut().unwrap();
831 crate::trace!("set_shape({src_shape:?})");
832
833 if !fr.shape.is_shape(src_shape) {
834 return Err(ReflectError::WrongShape {
835 expected: fr.shape,
836 actual: src_shape,
837 });
838 }
839
840 fr.deinit();
841
842 unsafe {
845 fr.data.copy_from(src_value, fr.shape).unwrap();
848 }
849
850 unsafe {
852 fr.mark_as_init();
853 }
854
855 Ok(self)
856 }
857
858 pub unsafe fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
868 where
869 F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
870 {
871 self.require_active()?;
872 let frame = self.frames.last_mut().unwrap();
873
874 frame.deinit();
875 f(frame.data)?;
876
877 unsafe {
879 frame.mark_as_init();
880 }
881
882 Ok(self)
883 }
884
885 #[inline]
894 pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
895 let frame = self.frames.last().unwrap();
896
897 let Some(default_fn) = frame.shape.vtable.default_in_place else {
898 return Err(ReflectError::OperationFailed {
899 shape: frame.shape,
900 operation: "type does not implement Default",
901 });
902 };
903
904 unsafe {
907 self.set_from_function(move |ptr| {
908 default_fn(ptr);
909 Ok(())
910 })
911 }
912 }
913
914 pub unsafe fn set_from_peek(&mut self, peek: &Peek<'_, '_>) -> Result<&mut Self, ReflectError> {
925 self.require_active()?;
926
927 let src_ptr = peek.data();
929 let src_shape = peek.shape();
930
931 unsafe { self.set_shape(src_ptr, src_shape) }
933 }
934
935 pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
939 self.require_active()?;
940
941 let frame = self.frames.last_mut().unwrap();
942
943 let Some(parse_fn) = frame.shape.vtable.parse else {
945 return Err(ReflectError::OperationFailed {
946 shape: frame.shape,
947 operation: "Type does not support parsing from string",
948 });
949 };
950
951 frame.deinit();
953
954 let result = unsafe { parse_fn(s, frame.data) };
956 if let Err(_pe) = result {
957 return Err(ReflectError::OperationFailed {
959 shape: frame.shape,
960 operation: "Failed to parse string value",
961 });
962 }
963
964 unsafe {
966 frame.mark_as_init();
967 }
968 Ok(self)
969 }
970}
971
972impl<'facet> Partial<'facet> {
976 pub fn selected_variant(&self) -> Option<Variant> {
978 let frame = self.frames.last()?;
979
980 match &frame.tracker {
981 Tracker::Enum { variant, .. } => Some(**variant),
982 _ => None,
983 }
984 }
985
986 pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'static Variant)> {
988 let frame = self.frames.last()?;
989
990 if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
991 enum_def
992 .variants
993 .iter()
994 .enumerate()
995 .find(|(_, v)| v.name == variant_name)
996 } else {
997 None
998 }
999 }
1000
1001 pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
1017 self.require_active()?;
1018
1019 let frame = self.frames.last().unwrap();
1020 let enum_type = frame.get_enum_type()?;
1021
1022 if index >= enum_type.variants.len() {
1023 return Err(ReflectError::OperationFailed {
1024 shape: frame.shape,
1025 operation: "variant index out of bounds",
1026 });
1027 }
1028 let variant = &enum_type.variants[index];
1029
1030 self.select_variant_internal(&enum_type, variant)?;
1031 Ok(self)
1032 }
1033
1034 pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
1038 self.require_active()?;
1039
1040 let frame = self.frames.last_mut().unwrap();
1041 let enum_type = frame.get_enum_type()?;
1042
1043 let Some(variant) = enum_type.variants.iter().find(|v| v.name == variant_name) else {
1044 return Err(ReflectError::OperationFailed {
1045 shape: frame.shape,
1046 operation: "No variant found with the given name",
1047 });
1048 };
1049
1050 self.select_variant_internal(&enum_type, variant)?;
1051 Ok(self)
1052 }
1053
1054 pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
1059 self.require_active()?;
1060
1061 let frame = self.frames.last().unwrap();
1063
1064 let enum_type = match frame.shape.ty {
1066 Type::User(UserType::Enum(e)) => e,
1067 _ => {
1068 return Err(ReflectError::WasNotA {
1069 expected: "enum",
1070 actual: frame.shape,
1071 });
1072 }
1073 };
1074
1075 let Some(variant) = enum_type
1077 .variants
1078 .iter()
1079 .find(|v| v.discriminant == Some(discriminant))
1080 else {
1081 return Err(ReflectError::OperationFailed {
1082 shape: frame.shape,
1083 operation: "No variant found with the given discriminant",
1084 });
1085 };
1086
1087 self.select_variant_internal(&enum_type, variant)?;
1089
1090 Ok(self)
1091 }
1092}
1093
1094impl Partial<'_> {
1098 pub fn field_index(&self, field_name: &str) -> Option<usize> {
1103 let frame = self.frames.last()?;
1104
1105 match frame.shape.ty {
1106 Type::User(UserType::Struct(struct_def)) => {
1107 struct_def.fields.iter().position(|f| f.name == field_name)
1108 }
1109 Type::User(UserType::Enum(_)) => {
1110 if let Tracker::Enum { variant, .. } = &frame.tracker {
1112 variant
1113 .data
1114 .fields
1115 .iter()
1116 .position(|f| f.name == field_name)
1117 } else {
1118 None
1119 }
1120 }
1121 _ => None,
1122 }
1123 }
1124
1125 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
1127 let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
1128
1129 match &frame.tracker {
1130 Tracker::Uninit => Ok(false),
1131 Tracker::Init => Ok(true),
1132 Tracker::Struct { iset, .. } => Ok(iset.get(index)),
1133 Tracker::Enum { data, variant, .. } => {
1134 if data.get(index) {
1136 return Ok(true);
1137 }
1138
1139 if let Some(field) = variant.data.fields.get(index) {
1141 if let Type::User(UserType::Struct(field_struct)) = field.shape().ty {
1142 if field_struct.fields.is_empty() {
1143 return Ok(true);
1144 }
1145 }
1146 }
1147
1148 Ok(false)
1149 }
1150 Tracker::Option { building_inner } => {
1151 if index == 0 {
1153 Ok(!building_inner)
1154 } else {
1155 Err(ReflectError::InvalidOperation {
1156 operation: "is_field_set",
1157 reason: "Option only has one field (index 0)",
1158 })
1159 }
1160 }
1161 _ => Err(ReflectError::InvalidOperation {
1162 operation: "is_field_set",
1163 reason: "Current frame is not a struct, enum variant, or option",
1164 }),
1165 }
1166 }
1167
1168 pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
1173 self.require_active()?;
1174
1175 let frame = self.frames.last().unwrap();
1176 let fields = self.get_fields()?;
1177 let Some(idx) = fields.iter().position(|f| f.name == field_name) else {
1178 return Err(ReflectError::FieldError {
1179 shape: frame.shape,
1180 field_error: facet_core::FieldError::NoSuchField,
1181 });
1182 };
1183 self.begin_nth_field(idx)
1184 }
1185
1186 pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1190 self.require_active()?;
1191 let frame = self.frames.last_mut().unwrap();
1192
1193 let next_frame = match frame.shape.ty {
1194 Type::User(user_type) => match user_type {
1195 UserType::Struct(struct_type) => {
1196 Self::begin_nth_struct_field(frame, struct_type, idx)?
1197 }
1198 UserType::Enum(_) => {
1199 match &frame.tracker {
1201 Tracker::Enum { variant, .. } => {
1202 Self::begin_nth_enum_field(frame, variant, idx)?
1203 }
1204 _ => {
1205 return Err(ReflectError::OperationFailed {
1206 shape: frame.shape,
1207 operation: "must call select_variant before selecting enum fields",
1208 });
1209 }
1210 }
1211 }
1212 UserType::Union(_) => {
1213 return Err(ReflectError::OperationFailed {
1214 shape: frame.shape,
1215 operation: "cannot select a field from a union",
1216 });
1217 }
1218 UserType::Opaque => {
1219 return Err(ReflectError::OperationFailed {
1220 shape: frame.shape,
1221 operation: "cannot select a field from an opaque type",
1222 });
1223 }
1224 },
1225 Type::Sequence(sequence_type) => match sequence_type {
1226 SequenceType::Array(array_type) => {
1227 Self::begin_nth_array_element(frame, array_type, idx)?
1228 }
1229 SequenceType::Slice(_) => {
1230 return Err(ReflectError::OperationFailed {
1231 shape: frame.shape,
1232 operation: "cannot select a field from slices yet",
1233 });
1234 }
1235 },
1236 _ => {
1237 return Err(ReflectError::OperationFailed {
1238 shape: frame.shape,
1239 operation: "cannot select a field from this type",
1240 });
1241 }
1242 };
1243
1244 self.frames.push(next_frame);
1245 Ok(self)
1246 }
1247
1248 pub fn set_nth_field_to_default(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1257 self.require_active()?;
1258
1259 let frame = self.frames.last().unwrap();
1260 let fields = self.get_fields()?;
1261
1262 if idx >= fields.len() {
1263 return Err(ReflectError::OperationFailed {
1264 shape: frame.shape,
1265 operation: "field index out of bounds",
1266 });
1267 }
1268
1269 let field = fields[idx];
1270
1271 if let Some(field_default_fn) = field.vtable.default_fn {
1273 self.begin_nth_field(idx)?;
1274 unsafe {
1276 self.set_from_function(|ptr| {
1277 field_default_fn(ptr);
1278 Ok(())
1279 })?;
1280 }
1281 self.end()
1282 } else if field.shape().is(Characteristic::Default) {
1283 self.begin_nth_field(idx)?;
1284 self.set_default()?;
1285 self.end()
1286 } else {
1287 return Err(ReflectError::DefaultAttrButNoDefaultImpl {
1288 shape: field.shape(),
1289 });
1290 }
1291 }
1292
1293 pub fn steal_nth_field(
1297 &mut self,
1298 src: &mut Partial,
1299 field_index: usize,
1300 ) -> Result<&mut Self, ReflectError> {
1301 let dst_shape = self.shape();
1302 let src_shape = src.shape();
1303 if dst_shape != src_shape {
1304 return Err(ReflectError::HeistCancelledDifferentShapes {
1305 src_shape,
1306 dst_shape,
1307 });
1308 }
1309
1310 if !src.is_field_set(field_index)? {
1313 return Err(ReflectError::InvariantViolation {
1314 invariant: "stolen field must be initialized",
1315 });
1316 }
1317
1318 let maybe_fields = match src_shape.ty {
1319 Type::Primitive(_primitive_type) => None,
1320 Type::Sequence(_sequence_type) => None,
1321 Type::User(user_type) => match user_type {
1322 UserType::Struct(struct_type) => Some(struct_type.fields),
1323 UserType::Enum(_enum_type) => match self.selected_variant() {
1324 Some(variant) => Some(variant.data.fields),
1325 None => {
1326 return Err(ReflectError::InvariantViolation {
1327 invariant: "enum field thief must have variant selected",
1328 });
1329 }
1330 },
1331 UserType::Union(_union_type) => None,
1332 UserType::Opaque => None,
1333 },
1334 Type::Pointer(_pointer_type) => None,
1335 };
1336
1337 let Some(fields) = maybe_fields else {
1338 return Err(ReflectError::OperationFailed {
1339 shape: src_shape,
1340 operation: "fetching field list for steal_nth_field",
1341 });
1342 };
1343
1344 if field_index >= fields.len() {
1345 return Err(ReflectError::OperationFailed {
1346 shape: src_shape,
1347 operation: "field index out of bounds",
1348 });
1349 }
1350 let field = fields[field_index];
1351
1352 let src_frame = src.frames.last_mut().unwrap();
1353
1354 self.begin_nth_field(field_index)?;
1355 unsafe {
1356 self.set_from_function(|dst_field_ptr| {
1357 let src_field_ptr = src_frame.data.field_init_at(field.offset).as_const();
1358 dst_field_ptr
1359 .copy_from(src_field_ptr, field.shape())
1360 .unwrap();
1361 Ok(())
1362 })?;
1363 }
1364 self.end()?;
1365
1366 match &mut src_frame.tracker {
1368 Tracker::Uninit => {
1369 unreachable!("we just stole a field from src, it couldn't have been fully uninit")
1370 }
1371 Tracker::Init => {
1372 let mut iset = ISet::new(fields.len());
1375 iset.set_all();
1376 iset.unset(field_index);
1377 src_frame.tracker = Tracker::Struct {
1378 iset,
1379 current_child: None,
1380 }
1381 }
1382 Tracker::Array { .. } => unreachable!("can't steal fields from arrays"),
1383 Tracker::Struct { iset, .. } => {
1384 iset.unset(field_index);
1385 }
1386 Tracker::SmartPointer { .. } => {
1387 unreachable!("can't steal fields from smart pointers")
1388 }
1389 Tracker::SmartPointerSlice { .. } => {
1390 unreachable!("can't steal fields from smart pointer slices")
1391 }
1392 Tracker::Enum { data, .. } => {
1393 data.unset(field_index);
1394 }
1395 Tracker::List { .. } => {
1396 unreachable!("can't steal fields from lists")
1397 }
1398 Tracker::Map { .. } => {
1399 unreachable!("can't steal fields from maps")
1400 }
1401 Tracker::Option { .. } => {
1402 unreachable!("can't steal fields from options")
1403 }
1404 }
1405
1406 Ok(self)
1407 }
1408}
1409
1410impl Partial<'_> {
1414 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
1416 crate::trace!("begin_smart_ptr()");
1417 self.require_active()?;
1418 let frame = self.frames.last_mut().unwrap();
1419
1420 match &frame.shape.def {
1422 Def::Pointer(smart_ptr_def) if smart_ptr_def.constructible_from_pointee() => {
1423 let pointee_shape = match smart_ptr_def.pointee() {
1425 Some(shape) => shape,
1426 None => {
1427 return Err(ReflectError::OperationFailed {
1428 shape: frame.shape,
1429 operation: "Smart pointer must have a pointee shape",
1430 });
1431 }
1432 };
1433
1434 if pointee_shape.layout.sized_layout().is_ok() {
1435 if matches!(frame.tracker, Tracker::Uninit) {
1439 frame.tracker = Tracker::SmartPointer {
1440 is_initialized: false,
1441 };
1442 }
1443
1444 let inner_layout = match pointee_shape.layout.sized_layout() {
1445 Ok(layout) => layout,
1446 Err(_) => {
1447 return Err(ReflectError::Unsized {
1448 shape: pointee_shape,
1449 operation: "begin_smart_ptr, calculating inner value layout",
1450 });
1451 }
1452 };
1453 let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1454 let Some(inner_ptr) = NonNull::new(inner_ptr) else {
1455 return Err(ReflectError::OperationFailed {
1456 shape: frame.shape,
1457 operation: "failed to allocate memory for smart pointer inner value",
1458 });
1459 };
1460
1461 self.frames.push(Frame::new(
1463 PtrUninit::new(inner_ptr),
1464 pointee_shape,
1465 FrameOwnership::Owned,
1466 ));
1467 } else {
1468 if pointee_shape == str::SHAPE {
1470 crate::trace!("Pointee is str");
1471
1472 let string_layout = String::SHAPE
1474 .layout
1475 .sized_layout()
1476 .expect("String must have a sized layout");
1477 let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1478 let Some(string_ptr) = NonNull::new(string_ptr) else {
1479 return Err(ReflectError::OperationFailed {
1480 shape: frame.shape,
1481 operation: "failed to allocate memory for string",
1482 });
1483 };
1484 let mut frame = Frame::new(
1485 PtrUninit::new(string_ptr),
1486 String::SHAPE,
1487 FrameOwnership::Owned,
1488 );
1489 frame.tracker = Tracker::Uninit;
1490 self.frames.push(frame);
1491 } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1492 crate::trace!("Pointee is [{}]", _st.t);
1493
1494 let slice_builder_vtable = smart_ptr_def
1496 .vtable
1497 .slice_builder_vtable
1498 .ok_or(ReflectError::OperationFailed {
1499 shape: frame.shape,
1500 operation: "smart pointer does not support slice building",
1501 })?;
1502
1503 let builder_ptr = (slice_builder_vtable.new_fn)();
1505
1506 if let FrameOwnership::Owned = frame.ownership {
1508 if let Ok(layout) = frame.shape.layout.sized_layout() {
1509 if layout.size() > 0 {
1510 unsafe {
1511 alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1512 };
1513 }
1514 }
1515 }
1516
1517 frame.data = builder_ptr.as_uninit();
1519 frame.tracker = Tracker::SmartPointerSlice {
1520 vtable: slice_builder_vtable,
1521 building_item: false,
1522 };
1523 frame.ownership = FrameOwnership::ManagedElsewhere;
1525 } else {
1526 return Err(ReflectError::OperationFailed {
1527 shape: frame.shape,
1528 operation: "push_smart_ptr can only be called on pointers to supported pointee types",
1529 });
1530 }
1531 }
1532
1533 Ok(self)
1534 }
1535 _ => Err(ReflectError::OperationFailed {
1536 shape: frame.shape,
1537 operation: "push_smart_ptr can only be called on compatible types",
1538 }),
1539 }
1540 }
1541}
1542
1543impl Partial<'_> {
1547 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1555 crate::trace!("begin_list()");
1556 self.require_active()?;
1557 let frame = self.frames.last_mut().unwrap();
1558
1559 match &frame.tracker {
1560 Tracker::Uninit => {
1561 }
1563 Tracker::Init => {
1564 frame.tracker = Tracker::List {
1566 is_initialized: true,
1567 current_child: false,
1568 };
1569 return Ok(self);
1570 }
1571 Tracker::List { is_initialized, .. } => {
1572 if *is_initialized {
1573 return Ok(self);
1575 }
1576 }
1577 Tracker::SmartPointerSlice { .. } => {
1578 return Ok(self);
1580 }
1581 _ => {
1582 return Err(ReflectError::UnexpectedTracker {
1583 message: "begin_list called but tracker isn't something list-like",
1584 current_tracker: frame.tracker.kind(),
1585 });
1586 }
1587 };
1588
1589 let list_def = match &frame.shape.def {
1591 Def::List(list_def) => list_def,
1592 _ => {
1593 return Err(ReflectError::OperationFailed {
1594 shape: frame.shape,
1595 operation: "begin_list can only be called on List types",
1596 });
1597 }
1598 };
1599
1600 let init_fn = match list_def.vtable.init_in_place_with_capacity {
1602 Some(f) => f,
1603 None => {
1604 return Err(ReflectError::OperationFailed {
1605 shape: frame.shape,
1606 operation: "list type does not support initialization with capacity",
1607 });
1608 }
1609 };
1610
1611 unsafe {
1613 init_fn(frame.data, 0);
1614 }
1615
1616 frame.tracker = Tracker::List {
1618 is_initialized: true,
1619 current_child: false,
1620 };
1621
1622 Ok(self)
1623 }
1624
1625 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1628 crate::trace!("begin_list_item()");
1629 self.require_active()?;
1630 let frame = self.frames.last_mut().unwrap();
1631
1632 if let Tracker::SmartPointerSlice {
1634 building_item,
1635 vtable: _,
1636 } = &frame.tracker
1637 {
1638 if *building_item {
1639 return Err(ReflectError::OperationFailed {
1640 shape: frame.shape,
1641 operation: "already building an item, call end() first",
1642 });
1643 }
1644
1645 let element_shape = match &frame.shape.def {
1647 Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1648 Some(pointee_shape) => match &pointee_shape.ty {
1649 Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1650 _ => {
1651 return Err(ReflectError::OperationFailed {
1652 shape: frame.shape,
1653 operation: "smart pointer pointee is not a slice",
1654 });
1655 }
1656 },
1657 None => {
1658 return Err(ReflectError::OperationFailed {
1659 shape: frame.shape,
1660 operation: "smart pointer has no pointee",
1661 });
1662 }
1663 },
1664 _ => {
1665 return Err(ReflectError::OperationFailed {
1666 shape: frame.shape,
1667 operation: "expected smart pointer definition",
1668 });
1669 }
1670 };
1671
1672 crate::trace!("Pointee is a slice of {element_shape}");
1674 let element_layout = match element_shape.layout.sized_layout() {
1675 Ok(layout) => layout,
1676 Err(_) => {
1677 return Err(ReflectError::OperationFailed {
1678 shape: element_shape,
1679 operation: "cannot allocate unsized element",
1680 });
1681 }
1682 };
1683
1684 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1685 let Some(element_ptr) = NonNull::new(element_ptr) else {
1686 return Err(ReflectError::OperationFailed {
1687 shape: frame.shape,
1688 operation: "failed to allocate memory for list element",
1689 });
1690 };
1691
1692 crate::trace!("Pushing element frame, which we just allocated");
1694 let element_frame = Frame::new(
1695 PtrUninit::new(element_ptr),
1696 element_shape,
1697 FrameOwnership::Owned,
1698 );
1699 self.frames.push(element_frame);
1700
1701 let parent_idx = self.frames.len() - 2;
1704 if let Tracker::SmartPointerSlice { building_item, .. } =
1705 &mut self.frames[parent_idx].tracker
1706 {
1707 crate::trace!("Marking element frame as building item");
1708 *building_item = true;
1709 }
1710
1711 return Ok(self);
1712 }
1713
1714 let list_def = match &frame.shape.def {
1716 Def::List(list_def) => list_def,
1717 _ => {
1718 return Err(ReflectError::OperationFailed {
1719 shape: frame.shape,
1720 operation: "push can only be called on List types",
1721 });
1722 }
1723 };
1724
1725 match &mut frame.tracker {
1727 Tracker::List {
1728 is_initialized: true,
1729 current_child,
1730 } => {
1731 if *current_child {
1732 return Err(ReflectError::OperationFailed {
1733 shape: frame.shape,
1734 operation: "already pushing an element, call pop() first",
1735 });
1736 }
1737 *current_child = true;
1738 }
1739 _ => {
1740 return Err(ReflectError::OperationFailed {
1741 shape: frame.shape,
1742 operation: "must call begin_list() before push()",
1743 });
1744 }
1745 }
1746
1747 let element_shape = list_def.t();
1749
1750 let element_layout = match element_shape.layout.sized_layout() {
1752 Ok(layout) => layout,
1753 Err(_) => {
1754 return Err(ReflectError::Unsized {
1755 shape: element_shape,
1756 operation: "begin_list_item: calculating element layout",
1757 });
1758 }
1759 };
1760 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1761
1762 let Some(element_ptr) = NonNull::new(element_ptr) else {
1763 return Err(ReflectError::OperationFailed {
1764 shape: frame.shape,
1765 operation: "failed to allocate memory for list element",
1766 });
1767 };
1768
1769 self.frames.push(Frame::new(
1771 PtrUninit::new(element_ptr),
1772 element_shape,
1773 FrameOwnership::Owned,
1774 ));
1775
1776 Ok(self)
1777 }
1778}
1779
1780impl Partial<'_> {
1784 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1789 self.require_active()?;
1790 let frame = self.frames.last_mut().unwrap();
1791
1792 let map_def = match &frame.shape.def {
1794 Def::Map(map_def) => map_def,
1795 _ => {
1796 return Err(ReflectError::OperationFailed {
1797 shape: frame.shape,
1798 operation: "begin_map can only be called on Map types",
1799 });
1800 }
1801 };
1802
1803 let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1804
1805 unsafe {
1807 init_fn(frame.data, 0);
1808 }
1809
1810 frame.tracker = Tracker::Map {
1812 is_initialized: true,
1813 insert_state: MapInsertState::Idle,
1814 };
1815
1816 Ok(self)
1817 }
1818
1819 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1823 self.require_active()?;
1824 let frame = self.frames.last_mut().unwrap();
1825
1826 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1828 (
1829 Def::Map(map_def),
1830 Tracker::Map {
1831 is_initialized: true,
1832 insert_state,
1833 },
1834 ) => {
1835 match insert_state {
1836 MapInsertState::Idle => {
1837 *insert_state = MapInsertState::PushingKey { key_ptr: None };
1839 }
1840 MapInsertState::PushingKey { key_ptr } => {
1841 if key_ptr.is_some() {
1842 return Err(ReflectError::OperationFailed {
1843 shape: frame.shape,
1844 operation: "already pushing a key, call end() first",
1845 });
1846 }
1847 }
1848 _ => {
1849 return Err(ReflectError::OperationFailed {
1850 shape: frame.shape,
1851 operation: "must complete current operation before begin_key()",
1852 });
1853 }
1854 }
1855 map_def
1856 }
1857 _ => {
1858 return Err(ReflectError::OperationFailed {
1859 shape: frame.shape,
1860 operation: "must call begin_map() before begin_key()",
1861 });
1862 }
1863 };
1864
1865 let key_shape = map_def.k();
1867
1868 let key_layout = match key_shape.layout.sized_layout() {
1870 Ok(layout) => layout,
1871 Err(_) => {
1872 return Err(ReflectError::Unsized {
1873 shape: key_shape,
1874 operation: "begin_key allocating key",
1875 });
1876 }
1877 };
1878 let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1879
1880 let Some(key_ptr_raw) = NonNull::new(key_ptr_raw) else {
1881 return Err(ReflectError::OperationFailed {
1882 shape: frame.shape,
1883 operation: "failed to allocate memory for map key",
1884 });
1885 };
1886
1887 match &mut frame.tracker {
1889 Tracker::Map {
1890 insert_state: MapInsertState::PushingKey { key_ptr: kp },
1891 ..
1892 } => {
1893 *kp = Some(PtrUninit::new(key_ptr_raw));
1894 }
1895 _ => unreachable!(),
1896 }
1897
1898 self.frames.push(Frame::new(
1900 PtrUninit::new(key_ptr_raw),
1901 key_shape,
1902 FrameOwnership::ManagedElsewhere, ));
1904
1905 Ok(self)
1906 }
1907
1908 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1911 self.require_active()?;
1912 let frame = self.frames.last_mut().unwrap();
1913
1914 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1916 (
1917 Def::Map(map_def),
1918 Tracker::Map {
1919 insert_state: MapInsertState::PushingValue { value_ptr, .. },
1920 ..
1921 },
1922 ) => {
1923 if value_ptr.is_some() {
1924 return Err(ReflectError::OperationFailed {
1925 shape: frame.shape,
1926 operation: "already pushing a value, call pop() first",
1927 });
1928 }
1929 map_def
1930 }
1931 _ => {
1932 return Err(ReflectError::OperationFailed {
1933 shape: frame.shape,
1934 operation: "must complete key before push_value()",
1935 });
1936 }
1937 };
1938
1939 let value_shape = map_def.v();
1941
1942 let value_layout = match value_shape.layout.sized_layout() {
1944 Ok(layout) => layout,
1945 Err(_) => {
1946 return Err(ReflectError::Unsized {
1947 shape: value_shape,
1948 operation: "begin_value allocating value",
1949 });
1950 }
1951 };
1952 let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1953
1954 let Some(value_ptr_raw) = NonNull::new(value_ptr_raw) else {
1955 return Err(ReflectError::OperationFailed {
1956 shape: frame.shape,
1957 operation: "failed to allocate memory for map value",
1958 });
1959 };
1960
1961 match &mut frame.tracker {
1963 Tracker::Map {
1964 insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1965 ..
1966 } => {
1967 *vp = Some(PtrUninit::new(value_ptr_raw));
1968 }
1969 _ => unreachable!(),
1970 }
1971
1972 self.frames.push(Frame::new(
1974 PtrUninit::new(value_ptr_raw),
1975 value_shape,
1976 FrameOwnership::ManagedElsewhere, ));
1978
1979 Ok(self)
1980 }
1981}
1982
1983impl Partial<'_> {
1987 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
1989 self.require_active()?;
1990 let frame = self.frames.last_mut().unwrap();
1991
1992 let option_def = match frame.shape.def {
1994 Def::Option(def) => def,
1995 _ => {
1996 return Err(ReflectError::WasNotA {
1997 expected: "Option",
1998 actual: frame.shape,
1999 });
2000 }
2001 };
2002
2003 if matches!(frame.tracker, Tracker::Uninit) {
2005 frame.tracker = Tracker::Option {
2006 building_inner: true,
2007 };
2008 }
2009
2010 let inner_shape = option_def.t;
2012
2013 let inner_layout =
2015 inner_shape
2016 .layout
2017 .sized_layout()
2018 .map_err(|_| ReflectError::Unsized {
2019 shape: inner_shape,
2020 operation: "begin_some, allocating Option inner value",
2021 })?;
2022
2023 let inner_data = if inner_layout.size() == 0 {
2024 PtrUninit::new(NonNull::<u8>::dangling())
2026 } else {
2027 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2029 let Some(ptr) = NonNull::new(ptr) else {
2030 alloc::alloc::handle_alloc_error(inner_layout);
2031 };
2032 PtrUninit::new(ptr)
2033 };
2034
2035 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
2037 self.frames.push(inner_frame);
2038
2039 Ok(self)
2040 }
2041
2042 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
2044 self.require_active()?;
2045
2046 let (inner_shape, has_try_from, parent_shape) = {
2048 let frame = self.frames.last().unwrap();
2049 if let Some(inner_shape) = frame.shape.inner {
2050 let has_try_from = frame.shape.vtable.try_from.is_some();
2051 (Some(inner_shape), has_try_from, frame.shape)
2052 } else {
2053 (None, false, frame.shape)
2054 }
2055 };
2056
2057 if let Some(inner_shape) = inner_shape {
2058 if has_try_from {
2059 let inner_layout =
2066 inner_shape
2067 .layout
2068 .sized_layout()
2069 .map_err(|_| ReflectError::Unsized {
2070 shape: inner_shape,
2071 operation: "begin_inner, getting inner layout",
2072 })?;
2073
2074 let inner_data = if inner_layout.size() == 0 {
2075 PtrUninit::new(NonNull::<u8>::dangling())
2077 } else {
2078 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2080 let Some(ptr) = NonNull::new(ptr) else {
2081 alloc::alloc::handle_alloc_error(inner_layout);
2082 };
2083 PtrUninit::new(ptr)
2084 };
2085
2086 trace!(
2090 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
2091 );
2092 self.frames
2093 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2094
2095 Ok(self)
2096 } else {
2097 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
2100 self.begin_nth_field(0)
2101 }
2102 } else {
2103 Err(ReflectError::OperationFailed {
2104 shape: parent_shape,
2105 operation: "type does not have an inner value",
2106 })
2107 }
2108 }
2109
2110 pub fn begin_custom_deserialization(&mut self) -> Result<&mut Self, ReflectError> {
2113 self.require_active()?;
2114
2115 let current_frame = self.frames.last().unwrap();
2116 let target_shape = current_frame.shape;
2117 if let Some(field) = self.parent_field() {
2118 if field.vtable.deserialize_with.is_some() {
2119 let Some(FieldAttribute::DeserializeFrom(source_shape)) = field
2122 .attributes
2123 .iter()
2124 .find(|&p| matches!(p, FieldAttribute::DeserializeFrom(_)))
2125 else {
2126 panic!("expected field attribute to be present with deserialize_with");
2127 };
2128 let source_data = source_shape.allocate().map_err(|_| ReflectError::Unsized {
2129 shape: target_shape,
2130 operation: "Not a Sized type",
2131 })?;
2132
2133 trace!(
2134 "begin_custom_deserialization: Creating frame for deserialization type {source_shape}"
2135 );
2136 let mut new_frame = Frame::new(source_data, source_shape, FrameOwnership::Owned);
2137 new_frame.using_custom_deserialization = true;
2138 self.frames.push(new_frame);
2139
2140 Ok(self)
2141 } else {
2142 Err(ReflectError::OperationFailed {
2143 shape: target_shape,
2144 operation: "field does not have a deserialize_with function",
2145 })
2146 }
2147 } else {
2148 Err(ReflectError::OperationFailed {
2149 shape: target_shape,
2150 operation: "not currently processing a field",
2151 })
2152 }
2153 }
2154}
2155
2156impl<'facet> Partial<'facet> {
2160 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2164 where
2165 U: Facet<'facet>,
2166 {
2167 self.begin_nth_field(idx)?.set(value)?.end()
2168 }
2169
2170 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
2172 where
2173 U: Facet<'facet>,
2174 {
2175 self.begin_field(field_name)?.set(value)?.end()
2176 }
2177
2178 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2180 where
2181 U: Facet<'facet>,
2182 {
2183 self.begin_key()?.set(value)?.end()
2184 }
2185
2186 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2188 where
2189 U: Facet<'facet>,
2190 {
2191 self.begin_value()?.set(value)?.end()
2192 }
2193
2194 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2196 where
2197 U: Facet<'facet>,
2198 {
2199 self.begin_list_item()?.set(value)?.end()
2200 }
2201}
2202
2203impl<'facet> Partial<'facet> {
2207 fn select_variant_internal(
2216 &mut self,
2217 enum_type: &EnumType,
2218 variant: &'static Variant,
2219 ) -> Result<(), ReflectError> {
2220 let frame = self.frames.last().unwrap();
2222
2223 match enum_type.enum_repr {
2225 EnumRepr::RustNPO => {
2226 return Err(ReflectError::OperationFailed {
2227 shape: frame.shape,
2228 operation: "RustNPO enums are not supported for incremental building",
2229 });
2230 }
2231 EnumRepr::U8
2232 | EnumRepr::U16
2233 | EnumRepr::U32
2234 | EnumRepr::U64
2235 | EnumRepr::I8
2236 | EnumRepr::I16
2237 | EnumRepr::I32
2238 | EnumRepr::I64
2239 | EnumRepr::USize
2240 | EnumRepr::ISize => {
2241 }
2243 }
2244
2245 let Some(discriminant) = variant.discriminant else {
2246 return Err(ReflectError::OperationFailed {
2247 shape: frame.shape,
2248 operation: "trying to select an enum variant without a discriminant",
2249 });
2250 };
2251
2252 let fr = self.frames.last_mut().unwrap();
2254
2255 unsafe {
2257 match enum_type.enum_repr {
2258 EnumRepr::U8 => {
2259 let ptr = fr.data.as_mut_byte_ptr();
2260 *ptr = discriminant as u8;
2261 }
2262 EnumRepr::U16 => {
2263 let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
2264 *ptr = discriminant as u16;
2265 }
2266 EnumRepr::U32 => {
2267 let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
2268 *ptr = discriminant as u32;
2269 }
2270 EnumRepr::U64 => {
2271 let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
2272 *ptr = discriminant as u64;
2273 }
2274 EnumRepr::I8 => {
2275 let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
2276 *ptr = discriminant as i8;
2277 }
2278 EnumRepr::I16 => {
2279 let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
2280 *ptr = discriminant as i16;
2281 }
2282 EnumRepr::I32 => {
2283 let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
2284 *ptr = discriminant as i32;
2285 }
2286 EnumRepr::I64 => {
2287 let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
2288 *ptr = discriminant;
2289 }
2290 EnumRepr::USize => {
2291 let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
2292 *ptr = discriminant as usize;
2293 }
2294 EnumRepr::ISize => {
2295 let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
2296 *ptr = discriminant as isize;
2297 }
2298 _ => unreachable!("Already checked enum representation above"),
2299 }
2300 }
2301
2302 fr.tracker = Tracker::Enum {
2304 variant,
2305 data: ISet::new(variant.data.fields.len()),
2306 current_child: None,
2307 };
2308
2309 Ok(())
2310 }
2311
2312 fn get_fields(&self) -> Result<&'static [Field], ReflectError> {
2315 let frame = self.frames.last().unwrap();
2316 match frame.shape.ty {
2317 Type::Primitive(_) => Err(ReflectError::OperationFailed {
2318 shape: frame.shape,
2319 operation: "cannot select a field from a primitive type",
2320 }),
2321 Type::Sequence(_) => Err(ReflectError::OperationFailed {
2322 shape: frame.shape,
2323 operation: "cannot select a field from a sequence type",
2324 }),
2325 Type::User(user_type) => match user_type {
2326 UserType::Struct(struct_type) => Ok(struct_type.fields),
2327 UserType::Enum(_) => {
2328 let Tracker::Enum { variant, .. } = &frame.tracker else {
2329 return Err(ReflectError::OperationFailed {
2330 shape: frame.shape,
2331 operation: "must select variant before selecting enum fields",
2332 });
2333 };
2334 Ok(variant.data.fields)
2335 }
2336 UserType::Union(_) => Err(ReflectError::OperationFailed {
2337 shape: frame.shape,
2338 operation: "cannot select a field from a union type",
2339 }),
2340 UserType::Opaque => Err(ReflectError::OperationFailed {
2341 shape: frame.shape,
2342 operation: "opaque types cannot be reflected upon",
2343 }),
2344 },
2345 Type::Pointer(_) => Err(ReflectError::OperationFailed {
2346 shape: frame.shape,
2347 operation: "cannot select a field from a pointer type",
2348 }),
2349 }
2350 }
2351
2352 fn begin_nth_struct_field(
2354 frame: &mut Frame,
2355 struct_type: StructType,
2356 idx: usize,
2357 ) -> Result<Frame, ReflectError> {
2358 if idx >= struct_type.fields.len() {
2359 return Err(ReflectError::OperationFailed {
2360 shape: frame.shape,
2361 operation: "field index out of bounds",
2362 });
2363 }
2364 let field = &struct_type.fields[idx];
2365
2366 if !matches!(frame.tracker, Tracker::Struct { .. }) {
2367 frame.tracker = Tracker::Struct {
2368 iset: ISet::new(struct_type.fields.len()),
2369 current_child: None,
2370 }
2371 }
2372
2373 let was_field_init = match &mut frame.tracker {
2374 Tracker::Struct {
2375 iset,
2376 current_child,
2377 } => {
2378 *current_child = Some(idx);
2379 iset.get(idx)
2380 }
2381 _ => unreachable!(),
2382 };
2383
2384 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2386 let field_shape = field.shape();
2387
2388 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2389 if was_field_init {
2390 unsafe {
2391 next_frame.mark_as_init();
2393 }
2394 }
2395
2396 Ok(next_frame)
2397 }
2398
2399 fn begin_nth_array_element(
2401 frame: &mut Frame,
2402 array_type: ArrayType,
2403 idx: usize,
2404 ) -> Result<Frame, ReflectError> {
2405 if idx >= array_type.n {
2406 return Err(ReflectError::OperationFailed {
2407 shape: frame.shape,
2408 operation: "array index out of bounds",
2409 });
2410 }
2411
2412 if array_type.n > 63 {
2413 return Err(ReflectError::OperationFailed {
2414 shape: frame.shape,
2415 operation: "arrays larger than 63 elements are not yet supported",
2416 });
2417 }
2418
2419 match &frame.tracker {
2421 Tracker::Uninit => {
2422 frame.tracker = Tracker::Array {
2424 iset: ISet::default(),
2425 current_child: None,
2426 };
2427 }
2428 Tracker::Array { .. } => {
2429 }
2431 _other => {
2432 return Err(ReflectError::OperationFailed {
2433 shape: frame.shape,
2434 operation: "unexpected tracker state: expected Uninit or Array",
2435 });
2436 }
2437 }
2438
2439 match &mut frame.tracker {
2440 Tracker::Array {
2441 iset,
2442 current_child,
2443 } => {
2444 *current_child = Some(idx);
2445 let was_field_init = iset.get(idx);
2446
2447 let Ok(element_layout) = array_type.t.layout.sized_layout() else {
2449 return Err(ReflectError::Unsized {
2450 shape: array_type.t,
2451 operation: "begin_nth_element, calculating array element offset",
2452 });
2453 };
2454 let offset = element_layout.size() * idx;
2455 let element_data = unsafe { frame.data.field_uninit_at(offset) };
2456
2457 let mut next_frame = Frame::new(element_data, array_type.t, FrameOwnership::Field);
2458 if was_field_init {
2459 unsafe {
2461 next_frame.mark_as_init();
2462 }
2463 }
2464 Ok(next_frame)
2465 }
2466 _ => unreachable!(),
2467 }
2468 }
2469
2470 fn begin_nth_enum_field(
2472 frame: &mut Frame,
2473 variant: &'static Variant,
2474 idx: usize,
2475 ) -> Result<Frame, ReflectError> {
2476 if idx >= variant.data.fields.len() {
2477 return Err(ReflectError::OperationFailed {
2478 shape: frame.shape,
2479 operation: "enum field index out of bounds",
2480 });
2481 }
2482
2483 let field = &variant.data.fields[idx];
2484
2485 let was_field_init = match &mut frame.tracker {
2487 Tracker::Enum {
2488 data,
2489 current_child,
2490 ..
2491 } => {
2492 *current_child = Some(idx);
2493 data.get(idx)
2494 }
2495 _ => {
2496 return Err(ReflectError::OperationFailed {
2497 shape: frame.shape,
2498 operation: "selecting a field on an enum requires selecting a variant first",
2499 });
2500 }
2501 };
2502
2503 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2506 let field_shape = field.shape();
2507
2508 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2509 if was_field_init {
2510 unsafe {
2512 next_frame.mark_as_init();
2513 }
2514 }
2515
2516 Ok(next_frame)
2517 }
2518
2519 #[inline]
2521 pub(crate) fn require_active(&self) -> Result<(), ReflectError> {
2522 if self.state == PartialState::Active {
2523 Ok(())
2524 } else {
2525 Err(ReflectError::InvariantViolation {
2526 invariant: "Cannot use Partial after it has been built or poisoned",
2527 })
2528 }
2529 }
2530}