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, KnownPointer, PtrConst,
19 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 let parent_frame = self.frames.last_mut().unwrap();
148
149 trace!(
150 "end(): Popped {} (tracker {:?}), Parent {} (tracker {:?})",
151 popped_frame.shape,
152 popped_frame.tracker.kind(),
153 parent_frame.shape,
154 parent_frame.tracker.kind()
155 );
156
157 let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
162 && parent_frame.shape.inner.is_some()
163 && parent_frame.shape.inner.unwrap() == popped_frame.shape
164 && parent_frame.shape.vtable.try_from.is_some();
165
166 if needs_conversion {
167 trace!(
168 "Detected implicit conversion needed from {} to {}",
169 popped_frame.shape, parent_frame.shape
170 );
171 if let Some(try_from_fn) = parent_frame.shape.vtable.try_from {
173 let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
174 let inner_shape = popped_frame.shape;
175
176 trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
177 let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
178
179 if let Err(e) = result {
180 trace!("Conversion failed: {e:?}");
181
182 if let FrameOwnership::Owned = popped_frame.ownership {
184 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
185 if layout.size() > 0 {
186 trace!(
187 "Deallocating conversion frame memory after failure: size={}, align={}",
188 layout.size(),
189 layout.align()
190 );
191 unsafe {
192 alloc::alloc::dealloc(
193 popped_frame.data.as_mut_byte_ptr(),
194 layout,
195 );
196 }
197 }
198 }
199 }
200
201 return Err(ReflectError::TryFromError {
202 src_shape: inner_shape,
203 dst_shape: parent_frame.shape,
204 inner: e,
205 });
206 }
207
208 trace!("Conversion succeeded, marking parent as initialized");
209 parent_frame.tracker = Tracker::Init;
210
211 if let FrameOwnership::Owned = popped_frame.ownership {
213 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
214 if layout.size() > 0 {
215 trace!(
216 "Deallocating conversion frame memory: size={}, align={}",
217 layout.size(),
218 layout.align()
219 );
220 unsafe {
221 alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
222 }
223 }
224 }
225 }
226
227 return Ok(self);
228 }
229 }
230
231 match &mut parent_frame.tracker {
232 Tracker::Struct {
233 iset,
234 current_child,
235 } => {
236 if let Some(idx) = *current_child {
237 iset.set(idx);
238 *current_child = None;
239 }
240 }
241 Tracker::Array {
242 iset,
243 current_child,
244 } => {
245 if let Some(idx) = *current_child {
246 iset.set(idx);
247 *current_child = None;
248 }
249 }
250 Tracker::SmartPointer { is_initialized } => {
251 if let Def::Pointer(smart_ptr_def) = parent_frame.shape.def {
253 let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn else {
254 return Err(ReflectError::OperationFailed {
255 shape: parent_frame.shape,
256 operation: "SmartPointer missing new_into_fn",
257 });
258 };
259
260 let inner_ptr = PtrMut::new(unsafe {
262 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
263 });
264
265 unsafe {
267 new_into_fn(parent_frame.data, inner_ptr);
268 }
269
270 popped_frame.tracker = Tracker::Uninit;
272
273 popped_frame.dealloc();
275
276 *is_initialized = true;
277 }
278 }
279 Tracker::Enum {
280 data,
281 current_child,
282 ..
283 } => {
284 if let Some(idx) = *current_child {
285 data.set(idx);
286 *current_child = None;
287 }
288 }
289 Tracker::List {
290 is_initialized: true,
291 current_child,
292 } => {
293 if *current_child {
294 if let Def::List(list_def) = parent_frame.shape.def {
296 let Some(push_fn) = list_def.vtable.push else {
297 return Err(ReflectError::OperationFailed {
298 shape: parent_frame.shape,
299 operation: "List missing push function",
300 });
301 };
302
303 let element_ptr = PtrMut::new(unsafe {
305 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
306 });
307
308 unsafe {
310 push_fn(
311 PtrMut::new(NonNull::new_unchecked(
312 parent_frame.data.as_mut_byte_ptr(),
313 )),
314 element_ptr,
315 );
316 }
317
318 popped_frame.tracker = Tracker::Uninit;
320 popped_frame.dealloc();
321
322 *current_child = false;
323 }
324 }
325 }
326 Tracker::Map {
327 is_initialized: true,
328 insert_state,
329 } => {
330 match insert_state {
331 MapInsertState::PushingKey { key_ptr } => {
332 if let Some(key_ptr) = key_ptr {
334 *insert_state = MapInsertState::PushingValue {
336 key_ptr: *key_ptr,
337 value_ptr: None,
338 };
339 }
340 }
341 MapInsertState::PushingValue { key_ptr, value_ptr } => {
342 if let (Some(value_ptr), Def::Map(map_def)) =
344 (value_ptr, parent_frame.shape.def)
345 {
346 let insert_fn = map_def.vtable.insert_fn;
347
348 unsafe {
350 insert_fn(
351 PtrMut::new(NonNull::new_unchecked(
352 parent_frame.data.as_mut_byte_ptr(),
353 )),
354 PtrMut::new(NonNull::new_unchecked(key_ptr.as_mut_byte_ptr())),
355 PtrMut::new(NonNull::new_unchecked(
356 value_ptr.as_mut_byte_ptr(),
357 )),
358 );
359 }
360
361 if let Ok(key_shape) = map_def.k().layout.sized_layout() {
367 if key_shape.size() > 0 {
368 unsafe {
369 alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
370 }
371 }
372 }
373 if let Ok(value_shape) = map_def.v().layout.sized_layout() {
374 if value_shape.size() > 0 {
375 unsafe {
376 alloc::alloc::dealloc(
377 value_ptr.as_mut_byte_ptr(),
378 value_shape,
379 );
380 }
381 }
382 }
383
384 *insert_state = MapInsertState::Idle;
386 }
387 }
388 MapInsertState::Idle => {
389 }
391 }
392 }
393 Tracker::Option { building_inner } => {
394 if *building_inner {
396 if let Def::Option(option_def) = parent_frame.shape.def {
397 let init_some_fn = option_def.vtable.init_some_fn;
399
400 let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
402
403 unsafe {
405 init_some_fn(parent_frame.data, inner_value_ptr);
406 }
407
408 if let FrameOwnership::Owned = popped_frame.ownership {
410 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
411 if layout.size() > 0 {
412 unsafe {
413 alloc::alloc::dealloc(
414 popped_frame.data.as_mut_byte_ptr(),
415 layout,
416 );
417 }
418 }
419 }
420 }
421
422 *building_inner = false;
424 } else {
425 return Err(ReflectError::OperationFailed {
426 shape: parent_frame.shape,
427 operation: "Option frame without Option definition",
428 });
429 }
430 }
431 }
432 Tracker::Uninit | Tracker::Init => {
433 match &parent_frame.shape.def {
436 Def::Pointer(smart_ptr_def) => {
437 let pointee =
438 smart_ptr_def
439 .pointee()
440 .ok_or(ReflectError::InvariantViolation {
441 invariant: "pointer type doesn't have a pointee",
442 })?;
443
444 if !pointee.is_shape(str::SHAPE) {
445 return Err(ReflectError::InvariantViolation {
446 invariant: "only T=str is supported when building SmartPointer<T> and T is unsized",
447 });
448 }
449
450 if !popped_frame.shape.is_shape(String::SHAPE) {
451 return Err(ReflectError::InvariantViolation {
452 invariant: "the popped frame should be String when building a SmartPointer<T>",
453 });
454 }
455
456 popped_frame.require_full_initialization()?;
457
458 use alloc::{rc::Rc, string::String, sync::Arc};
463 let parent_shape = parent_frame.shape;
464
465 let Some(known) = smart_ptr_def.known else {
466 return Err(ReflectError::OperationFailed {
467 shape: parent_shape,
468 operation: "SmartPointerStr for unknown smart pointer kind",
469 });
470 };
471
472 parent_frame.deinit();
473
474 let string_ptr = popped_frame.data.as_mut_byte_ptr() as *mut String;
476 let string_value = unsafe { core::ptr::read(string_ptr) };
477
478 match known {
479 KnownPointer::Box => {
480 let boxed: Box<str> = string_value.into_boxed_str();
481 unsafe {
482 core::ptr::write(
483 parent_frame.data.as_mut_byte_ptr() as *mut Box<str>,
484 boxed,
485 );
486 }
487 }
488 KnownPointer::Arc => {
489 let arc: Arc<str> = Arc::from(string_value.into_boxed_str());
490 unsafe {
491 core::ptr::write(
492 parent_frame.data.as_mut_byte_ptr() as *mut Arc<str>,
493 arc,
494 );
495 }
496 }
497 KnownPointer::Rc => {
498 let rc: Rc<str> = Rc::from(string_value.into_boxed_str());
499 unsafe {
500 core::ptr::write(
501 parent_frame.data.as_mut_byte_ptr() as *mut Rc<str>,
502 rc,
503 );
504 }
505 }
506 _ => {
507 return Err(ReflectError::OperationFailed {
508 shape: parent_shape,
509 operation: "Don't know how to build this pointer type",
510 });
511 }
512 }
513
514 parent_frame.tracker = Tracker::Init;
515
516 popped_frame.tracker = Tracker::Uninit;
517 popped_frame.dealloc();
518 }
519 _ => {
520 unreachable!(
521 "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"
522 )
523 }
524 }
525 }
526 Tracker::SmartPointerSlice {
527 vtable,
528 building_item,
529 } => {
530 if *building_item {
531 let element_ptr = PtrMut::new(unsafe {
533 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
534 });
535
536 crate::trace!("Pushing element to slice builder");
538 unsafe {
539 let parent_ptr = parent_frame.data.assume_init();
540 (vtable.push_fn)(parent_ptr, element_ptr);
541 }
542
543 popped_frame.tracker = Tracker::Uninit;
544 popped_frame.dealloc();
545
546 if let Tracker::SmartPointerSlice {
547 building_item: bi, ..
548 } = &mut parent_frame.tracker
549 {
550 *bi = false;
551 }
552 }
553 }
554 _ => {}
555 }
556
557 Ok(self)
558 }
559
560 pub fn path(&self) -> String {
563 let mut out = String::new();
564
565 let mut path_components = Vec::new();
566 for (i, frame) in self.frames.iter().enumerate() {
569 match frame.shape.ty {
570 Type::User(user_type) => match user_type {
571 UserType::Struct(struct_type) => {
572 let mut field_str = None;
574 if let Tracker::Struct {
575 current_child: Some(idx),
576 ..
577 } = &frame.tracker
578 {
579 if let Some(field) = struct_type.fields.get(*idx) {
580 field_str = Some(field.name);
581 }
582 }
583 if i == 0 {
584 path_components.push(format!("{}", frame.shape));
586 }
587 if let Some(field_name) = field_str {
588 path_components.push(format!(".{field_name}"));
589 }
590 }
591 UserType::Enum(_enum_type) => {
592 if let Tracker::Enum {
594 variant,
595 current_child,
596 ..
597 } = &frame.tracker
598 {
599 if i == 0 {
600 path_components.push(format!("{}", frame.shape));
602 }
603 path_components.push(format!("::{}", variant.name));
604 if let Some(idx) = *current_child {
605 if let Some(field) = variant.data.fields.get(idx) {
606 path_components.push(format!(".{}", field.name));
607 }
608 }
609 } else if i == 0 {
610 path_components.push(format!("{}", frame.shape));
612 }
613 }
614 UserType::Union(_union_type) => {
615 path_components.push(format!("{}", frame.shape));
616 }
617 UserType::Opaque => {
618 path_components.push("<opaque>".to_string());
619 }
620 },
621 Type::Sequence(seq_type) => match seq_type {
622 facet_core::SequenceType::Array(_array_def) => {
623 if let Tracker::Array {
625 current_child: Some(idx),
626 ..
627 } = &frame.tracker
628 {
629 path_components.push(format!("[{idx}]"));
630 }
631 }
632 _ => {
634 path_components.push("[]".to_string());
636 }
637 },
638 Type::Pointer(_) => {
639 path_components.push("*".to_string());
641 }
642 _ => {
643 }
645 }
646 }
647 for component in path_components {
649 out.push_str(&component);
650 }
651 out
652 }
653}
654
655impl<'facet> Partial<'facet> {
659 pub fn build(&mut self) -> Result<HeapValue<'facet>, ReflectError> {
661 self.require_active()?;
662 if self.frames.len() != 1 {
663 self.state = PartialState::BuildFailed;
664 return Err(ReflectError::InvariantViolation {
665 invariant: "Partial::build() expects a single frame — call end() until that's the case",
666 });
667 }
668
669 let frame = self.frames.pop().unwrap();
670
671 if let Err(e) = frame.require_full_initialization() {
673 self.frames.push(frame);
675 self.state = PartialState::BuildFailed;
676 return Err(e);
677 }
678
679 if let Some(invariants_fn) = frame.shape.vtable.invariants {
681 let value_ptr = unsafe { frame.data.assume_init().as_const() };
683 let invariants_ok = unsafe { invariants_fn(value_ptr) };
684
685 if !invariants_ok {
686 self.frames.push(frame);
688 self.state = PartialState::BuildFailed;
689 return Err(ReflectError::InvariantViolation {
690 invariant: "Type invariants check failed",
691 });
692 }
693 }
694
695 self.state = PartialState::Built;
697
698 match frame
699 .shape
700 .layout
701 .sized_layout()
702 .map_err(|_layout_err| ReflectError::Unsized {
703 shape: frame.shape,
704 operation: "build (final check for sized layout)",
705 }) {
706 Ok(layout) => Ok(HeapValue {
707 guard: Some(Guard {
708 ptr: unsafe { NonNull::new_unchecked(frame.data.as_mut_byte_ptr()) },
709 layout,
710 }),
711 shape: frame.shape,
712 phantom: PhantomData,
713 }),
714 Err(e) => {
715 self.frames.push(frame);
717 self.state = PartialState::BuildFailed;
718 Err(e)
719 }
720 }
721 }
722}
723
724impl<'facet> Partial<'facet> {
728 pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
734 where
735 U: Facet<'facet>,
736 {
737 self.require_active()?;
738 struct DropVal<U> {
739 ptr: *mut U,
740 }
741 impl<U> Drop for DropVal<U> {
742 #[inline]
743 fn drop(&mut self) {
744 unsafe { core::ptr::drop_in_place(self.ptr) };
745 }
746 }
747
748 let mut value = ManuallyDrop::new(value);
749 let drop = DropVal {
750 ptr: (&mut value) as *mut ManuallyDrop<U> as *mut U,
751 };
752
753 let ptr_const = PtrConst::new(unsafe { NonNull::new_unchecked(drop.ptr) });
754 unsafe {
755 self.set_shape(ptr_const, U::SHAPE)?
757 };
758 core::mem::forget(drop);
759
760 Ok(self)
761 }
762
763 #[inline]
777 pub unsafe fn set_shape(
778 &mut self,
779 src_value: PtrConst<'_>,
780 src_shape: &'static Shape,
781 ) -> Result<&mut Self, ReflectError> {
782 self.require_active()?;
783
784 let fr = self.frames.last_mut().unwrap();
785 crate::trace!("set_shape({src_shape:?})");
786
787 if !fr.shape.is_shape(src_shape) {
788 return Err(ReflectError::WrongShape {
789 expected: fr.shape,
790 actual: src_shape,
791 });
792 }
793
794 fr.deinit();
795
796 unsafe {
799 fr.data.copy_from(src_value, fr.shape).unwrap();
802 }
803
804 unsafe {
806 fr.mark_as_init();
807 }
808
809 Ok(self)
810 }
811
812 pub unsafe fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
822 where
823 F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
824 {
825 self.require_active()?;
826 let frame = self.frames.last_mut().unwrap();
827
828 frame.deinit();
829 f(frame.data)?;
830
831 unsafe {
833 frame.mark_as_init();
834 }
835
836 Ok(self)
837 }
838
839 #[inline]
848 pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
849 let frame = self.frames.last().unwrap();
850
851 let Some(default_fn) = frame.shape.vtable.default_in_place else {
852 return Err(ReflectError::OperationFailed {
853 shape: frame.shape,
854 operation: "type does not implement Default",
855 });
856 };
857
858 unsafe {
861 self.set_from_function(move |ptr| {
862 default_fn(ptr);
863 Ok(())
864 })
865 }
866 }
867
868 pub unsafe fn set_from_peek(&mut self, peek: &Peek<'_, '_>) -> Result<&mut Self, ReflectError> {
879 self.require_active()?;
880
881 let src_ptr = peek.data();
883 let src_shape = peek.shape();
884
885 unsafe { self.set_shape(src_ptr, src_shape) }
887 }
888
889 pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
893 self.require_active()?;
894
895 let frame = self.frames.last_mut().unwrap();
896
897 let Some(parse_fn) = frame.shape.vtable.parse else {
899 return Err(ReflectError::OperationFailed {
900 shape: frame.shape,
901 operation: "Type does not support parsing from string",
902 });
903 };
904
905 frame.deinit();
907
908 let result = unsafe { parse_fn(s, frame.data) };
910 if let Err(_pe) = result {
911 return Err(ReflectError::OperationFailed {
913 shape: frame.shape,
914 operation: "Failed to parse string value",
915 });
916 }
917
918 unsafe {
920 frame.mark_as_init();
921 }
922 Ok(self)
923 }
924}
925
926impl<'facet> Partial<'facet> {
930 pub fn selected_variant(&self) -> Option<Variant> {
932 let frame = self.frames.last()?;
933
934 match &frame.tracker {
935 Tracker::Enum { variant, .. } => Some(**variant),
936 _ => None,
937 }
938 }
939
940 pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'static Variant)> {
942 let frame = self.frames.last()?;
943
944 if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
945 enum_def
946 .variants
947 .iter()
948 .enumerate()
949 .find(|(_, v)| v.name == variant_name)
950 } else {
951 None
952 }
953 }
954
955 pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
971 self.require_active()?;
972
973 let frame = self.frames.last().unwrap();
974 let enum_type = frame.get_enum_type()?;
975
976 if index >= enum_type.variants.len() {
977 return Err(ReflectError::OperationFailed {
978 shape: frame.shape,
979 operation: "variant index out of bounds",
980 });
981 }
982 let variant = &enum_type.variants[index];
983
984 self.select_variant_internal(&enum_type, variant)?;
985 Ok(self)
986 }
987
988 pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
992 self.require_active()?;
993
994 let frame = self.frames.last_mut().unwrap();
995 let enum_type = frame.get_enum_type()?;
996
997 let Some(variant) = enum_type.variants.iter().find(|v| v.name == variant_name) else {
998 return Err(ReflectError::OperationFailed {
999 shape: frame.shape,
1000 operation: "No variant found with the given name",
1001 });
1002 };
1003
1004 self.select_variant_internal(&enum_type, variant)?;
1005 Ok(self)
1006 }
1007
1008 pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
1013 self.require_active()?;
1014
1015 let frame = self.frames.last().unwrap();
1017
1018 let enum_type = match frame.shape.ty {
1020 Type::User(UserType::Enum(e)) => e,
1021 _ => {
1022 return Err(ReflectError::WasNotA {
1023 expected: "enum",
1024 actual: frame.shape,
1025 });
1026 }
1027 };
1028
1029 let Some(variant) = enum_type
1031 .variants
1032 .iter()
1033 .find(|v| v.discriminant == Some(discriminant))
1034 else {
1035 return Err(ReflectError::OperationFailed {
1036 shape: frame.shape,
1037 operation: "No variant found with the given discriminant",
1038 });
1039 };
1040
1041 self.select_variant_internal(&enum_type, variant)?;
1043
1044 Ok(self)
1045 }
1046}
1047
1048impl Partial<'_> {
1052 pub fn field_index(&self, field_name: &str) -> Option<usize> {
1057 let frame = self.frames.last()?;
1058
1059 match frame.shape.ty {
1060 Type::User(UserType::Struct(struct_def)) => {
1061 struct_def.fields.iter().position(|f| f.name == field_name)
1062 }
1063 Type::User(UserType::Enum(_)) => {
1064 if let Tracker::Enum { variant, .. } = &frame.tracker {
1066 variant
1067 .data
1068 .fields
1069 .iter()
1070 .position(|f| f.name == field_name)
1071 } else {
1072 None
1073 }
1074 }
1075 _ => None,
1076 }
1077 }
1078
1079 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
1081 let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
1082
1083 match &frame.tracker {
1084 Tracker::Uninit => Ok(false),
1085 Tracker::Init => Ok(true),
1086 Tracker::Struct { iset, .. } => Ok(iset.get(index)),
1087 Tracker::Enum { data, variant, .. } => {
1088 if data.get(index) {
1090 return Ok(true);
1091 }
1092
1093 if let Some(field) = variant.data.fields.get(index) {
1095 if let Type::User(UserType::Struct(field_struct)) = field.shape().ty {
1096 if field_struct.fields.is_empty() {
1097 return Ok(true);
1098 }
1099 }
1100 }
1101
1102 Ok(false)
1103 }
1104 Tracker::Option { building_inner } => {
1105 if index == 0 {
1107 Ok(!building_inner)
1108 } else {
1109 Err(ReflectError::InvalidOperation {
1110 operation: "is_field_set",
1111 reason: "Option only has one field (index 0)",
1112 })
1113 }
1114 }
1115 _ => Err(ReflectError::InvalidOperation {
1116 operation: "is_field_set",
1117 reason: "Current frame is not a struct, enum variant, or option",
1118 }),
1119 }
1120 }
1121
1122 pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
1127 self.require_active()?;
1128
1129 let frame = self.frames.last().unwrap();
1130 let fields = self.get_fields()?;
1131 let Some(idx) = fields.iter().position(|f| f.name == field_name) else {
1132 return Err(ReflectError::FieldError {
1133 shape: frame.shape,
1134 field_error: facet_core::FieldError::NoSuchField,
1135 });
1136 };
1137 self.begin_nth_field(idx)
1138 }
1139
1140 pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1144 self.require_active()?;
1145 let frame = self.frames.last_mut().unwrap();
1146
1147 let next_frame = match frame.shape.ty {
1148 Type::User(user_type) => match user_type {
1149 UserType::Struct(struct_type) => {
1150 Self::begin_nth_struct_field(frame, struct_type, idx)?
1151 }
1152 UserType::Enum(_) => {
1153 match &frame.tracker {
1155 Tracker::Enum { variant, .. } => {
1156 Self::begin_nth_enum_field(frame, variant, idx)?
1157 }
1158 _ => {
1159 return Err(ReflectError::OperationFailed {
1160 shape: frame.shape,
1161 operation: "must call select_variant before selecting enum fields",
1162 });
1163 }
1164 }
1165 }
1166 UserType::Union(_) => {
1167 return Err(ReflectError::OperationFailed {
1168 shape: frame.shape,
1169 operation: "cannot select a field from a union",
1170 });
1171 }
1172 UserType::Opaque => {
1173 return Err(ReflectError::OperationFailed {
1174 shape: frame.shape,
1175 operation: "cannot select a field from an opaque type",
1176 });
1177 }
1178 },
1179 Type::Sequence(sequence_type) => match sequence_type {
1180 SequenceType::Array(array_type) => {
1181 Self::begin_nth_array_element(frame, array_type, idx)?
1182 }
1183 SequenceType::Slice(_) => {
1184 return Err(ReflectError::OperationFailed {
1185 shape: frame.shape,
1186 operation: "cannot select a field from slices yet",
1187 });
1188 }
1189 },
1190 _ => {
1191 return Err(ReflectError::OperationFailed {
1192 shape: frame.shape,
1193 operation: "cannot select a field from this type",
1194 });
1195 }
1196 };
1197
1198 self.frames.push(next_frame);
1199 Ok(self)
1200 }
1201
1202 pub fn set_nth_field_to_default(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1211 self.require_active()?;
1212
1213 let frame = self.frames.last().unwrap();
1214 let fields = self.get_fields()?;
1215
1216 if idx >= fields.len() {
1217 return Err(ReflectError::OperationFailed {
1218 shape: frame.shape,
1219 operation: "field index out of bounds",
1220 });
1221 }
1222
1223 let field = fields[idx];
1224
1225 if let Some(field_default_fn) = field.vtable.default_fn {
1227 self.begin_nth_field(idx)?;
1228 unsafe {
1230 self.set_from_function(|ptr| {
1231 field_default_fn(ptr);
1232 Ok(())
1233 })?;
1234 }
1235 self.end()
1236 } else if field.shape().is(Characteristic::Default) {
1237 self.begin_nth_field(idx)?;
1238 self.set_default()?;
1239 self.end()
1240 } else {
1241 return Err(ReflectError::DefaultAttrButNoDefaultImpl {
1242 shape: field.shape(),
1243 });
1244 }
1245 }
1246
1247 pub fn steal_nth_field(
1251 &mut self,
1252 src: &mut Partial,
1253 field_index: usize,
1254 ) -> Result<&mut Self, ReflectError> {
1255 let dst_shape = self.shape();
1256 let src_shape = src.shape();
1257 if dst_shape != src_shape {
1258 return Err(ReflectError::HeistCancelledDifferentShapes {
1259 src_shape,
1260 dst_shape,
1261 });
1262 }
1263
1264 if !src.is_field_set(field_index)? {
1267 return Err(ReflectError::InvariantViolation {
1268 invariant: "stolen field must be initialized",
1269 });
1270 }
1271
1272 let maybe_fields = match src_shape.ty {
1273 Type::Primitive(_primitive_type) => None,
1274 Type::Sequence(_sequence_type) => None,
1275 Type::User(user_type) => match user_type {
1276 UserType::Struct(struct_type) => Some(struct_type.fields),
1277 UserType::Enum(_enum_type) => match self.selected_variant() {
1278 Some(variant) => Some(variant.data.fields),
1279 None => {
1280 return Err(ReflectError::InvariantViolation {
1281 invariant: "enum field thief must have variant selected",
1282 });
1283 }
1284 },
1285 UserType::Union(_union_type) => None,
1286 UserType::Opaque => None,
1287 },
1288 Type::Pointer(_pointer_type) => None,
1289 };
1290
1291 let Some(fields) = maybe_fields else {
1292 return Err(ReflectError::OperationFailed {
1293 shape: src_shape,
1294 operation: "fetching field list for steal_nth_field",
1295 });
1296 };
1297
1298 if field_index >= fields.len() {
1299 return Err(ReflectError::OperationFailed {
1300 shape: src_shape,
1301 operation: "field index out of bounds",
1302 });
1303 }
1304 let field = fields[field_index];
1305
1306 let src_frame = src.frames.last_mut().unwrap();
1307
1308 self.begin_nth_field(field_index)?;
1309 unsafe {
1310 self.set_from_function(|dst_field_ptr| {
1311 let src_field_ptr = src_frame.data.field_init_at(field.offset).as_const();
1312 dst_field_ptr
1313 .copy_from(src_field_ptr, field.shape())
1314 .unwrap();
1315 Ok(())
1316 })?;
1317 }
1318 self.end()?;
1319
1320 match &mut src_frame.tracker {
1322 Tracker::Uninit => {
1323 unreachable!("we just stole a field from src, it couldn't have been fully uninit")
1324 }
1325 Tracker::Init => {
1326 let mut iset = ISet::new(fields.len());
1329 iset.set_all();
1330 iset.unset(field_index);
1331 src_frame.tracker = Tracker::Struct {
1332 iset,
1333 current_child: None,
1334 }
1335 }
1336 Tracker::Array { .. } => unreachable!("can't steal fields from arrays"),
1337 Tracker::Struct { iset, .. } => {
1338 iset.unset(field_index);
1339 }
1340 Tracker::SmartPointer { .. } => {
1341 unreachable!("can't steal fields from smart pointers")
1342 }
1343 Tracker::SmartPointerSlice { .. } => {
1344 unreachable!("can't steal fields from smart pointer slices")
1345 }
1346 Tracker::Enum { data, .. } => {
1347 data.unset(field_index);
1348 }
1349 Tracker::List { .. } => {
1350 unreachable!("can't steal fields from lists")
1351 }
1352 Tracker::Map { .. } => {
1353 unreachable!("can't steal fields from maps")
1354 }
1355 Tracker::Option { .. } => {
1356 unreachable!("can't steal fields from options")
1357 }
1358 }
1359
1360 Ok(self)
1361 }
1362}
1363
1364impl Partial<'_> {
1368 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
1370 crate::trace!("begin_smart_ptr()");
1371 self.require_active()?;
1372 let frame = self.frames.last_mut().unwrap();
1373
1374 match &frame.shape.def {
1376 Def::Pointer(smart_ptr_def) => {
1377 match smart_ptr_def.known {
1379 Some(KnownPointer::Box)
1380 | Some(KnownPointer::Rc)
1381 | Some(KnownPointer::Arc)
1382 | Some(KnownPointer::SharedReference) => {
1383 }
1385 _ => {
1386 return Err(ReflectError::OperationFailed {
1387 shape: frame.shape,
1388 operation: "only the following pointers are currently supported: Box<T>, Rc<T>, Arc<T>, and &T",
1389 });
1390 }
1391 }
1392
1393 let pointee_shape = match smart_ptr_def.pointee() {
1395 Some(shape) => shape,
1396 None => {
1397 return Err(ReflectError::OperationFailed {
1398 shape: frame.shape,
1399 operation: "Box must have a pointee shape",
1400 });
1401 }
1402 };
1403
1404 if pointee_shape.layout.sized_layout().is_ok() {
1405 if matches!(frame.tracker, Tracker::Uninit) {
1409 frame.tracker = Tracker::SmartPointer {
1410 is_initialized: false,
1411 };
1412 }
1413
1414 let inner_layout = match pointee_shape.layout.sized_layout() {
1415 Ok(layout) => layout,
1416 Err(_) => {
1417 return Err(ReflectError::Unsized {
1418 shape: pointee_shape,
1419 operation: "begin_smart_ptr, calculating inner value layout",
1420 });
1421 }
1422 };
1423 let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1424 let Some(inner_ptr) = NonNull::new(inner_ptr) else {
1425 return Err(ReflectError::OperationFailed {
1426 shape: frame.shape,
1427 operation: "failed to allocate memory for smart pointer inner value",
1428 });
1429 };
1430
1431 self.frames.push(Frame::new(
1433 PtrUninit::new(inner_ptr),
1434 pointee_shape,
1435 FrameOwnership::Owned,
1436 ));
1437 } else {
1438 if pointee_shape == str::SHAPE {
1440 crate::trace!("Pointee is str");
1441
1442 let string_layout = String::SHAPE
1444 .layout
1445 .sized_layout()
1446 .expect("String must have a sized layout");
1447 let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1448 let Some(string_ptr) = NonNull::new(string_ptr) else {
1449 return Err(ReflectError::OperationFailed {
1450 shape: frame.shape,
1451 operation: "failed to allocate memory for string",
1452 });
1453 };
1454 let mut frame = Frame::new(
1455 PtrUninit::new(string_ptr),
1456 String::SHAPE,
1457 FrameOwnership::Owned,
1458 );
1459 frame.tracker = Tracker::Uninit;
1460 self.frames.push(frame);
1461 } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1462 crate::trace!("Pointee is [{}]", _st.t);
1463
1464 let slice_builder_vtable = smart_ptr_def
1466 .vtable
1467 .slice_builder_vtable
1468 .ok_or(ReflectError::OperationFailed {
1469 shape: frame.shape,
1470 operation: "smart pointer does not support slice building",
1471 })?;
1472
1473 let builder_ptr = (slice_builder_vtable.new_fn)();
1475
1476 if let FrameOwnership::Owned = frame.ownership {
1478 if let Ok(layout) = frame.shape.layout.sized_layout() {
1479 if layout.size() > 0 {
1480 unsafe {
1481 alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1482 };
1483 }
1484 }
1485 }
1486
1487 frame.data = builder_ptr.as_uninit();
1489 frame.tracker = Tracker::SmartPointerSlice {
1490 vtable: slice_builder_vtable,
1491 building_item: false,
1492 };
1493 frame.ownership = FrameOwnership::ManagedElsewhere;
1495 } else {
1496 todo!("unsupported unsize pointee shape: {}", pointee_shape)
1497 }
1498 }
1499
1500 Ok(self)
1501 }
1502 _ => Err(ReflectError::OperationFailed {
1503 shape: frame.shape,
1504 operation: "push_smart_ptr can only be called on compatible types",
1505 }),
1506 }
1507 }
1508}
1509
1510impl Partial<'_> {
1514 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1522 crate::trace!("begin_list()");
1523 self.require_active()?;
1524 let frame = self.frames.last_mut().unwrap();
1525
1526 match &frame.tracker {
1527 Tracker::Uninit => {
1528 }
1530 Tracker::Init => {
1531 frame.tracker = Tracker::List {
1533 is_initialized: true,
1534 current_child: false,
1535 };
1536 return Ok(self);
1537 }
1538 Tracker::List { is_initialized, .. } => {
1539 if *is_initialized {
1540 return Ok(self);
1542 }
1543 }
1544 Tracker::SmartPointerSlice { .. } => {
1545 return Ok(self);
1547 }
1548 _ => {
1549 return Err(ReflectError::UnexpectedTracker {
1550 message: "begin_list called but tracker isn't something list-like",
1551 current_tracker: frame.tracker.kind(),
1552 });
1553 }
1554 };
1555
1556 let list_def = match &frame.shape.def {
1558 Def::List(list_def) => list_def,
1559 _ => {
1560 return Err(ReflectError::OperationFailed {
1561 shape: frame.shape,
1562 operation: "begin_list can only be called on List types",
1563 });
1564 }
1565 };
1566
1567 let init_fn = match list_def.vtable.init_in_place_with_capacity {
1569 Some(f) => f,
1570 None => {
1571 return Err(ReflectError::OperationFailed {
1572 shape: frame.shape,
1573 operation: "list type does not support initialization with capacity",
1574 });
1575 }
1576 };
1577
1578 unsafe {
1580 init_fn(frame.data, 0);
1581 }
1582
1583 frame.tracker = Tracker::List {
1585 is_initialized: true,
1586 current_child: false,
1587 };
1588
1589 Ok(self)
1590 }
1591
1592 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1595 crate::trace!("begin_list_item()");
1596 self.require_active()?;
1597 let frame = self.frames.last_mut().unwrap();
1598
1599 if let Tracker::SmartPointerSlice {
1601 building_item,
1602 vtable: _,
1603 } = &frame.tracker
1604 {
1605 if *building_item {
1606 return Err(ReflectError::OperationFailed {
1607 shape: frame.shape,
1608 operation: "already building an item, call end() first",
1609 });
1610 }
1611
1612 let element_shape = match &frame.shape.def {
1614 Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1615 Some(pointee_shape) => match &pointee_shape.ty {
1616 Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1617 _ => {
1618 return Err(ReflectError::OperationFailed {
1619 shape: frame.shape,
1620 operation: "smart pointer pointee is not a slice",
1621 });
1622 }
1623 },
1624 None => {
1625 return Err(ReflectError::OperationFailed {
1626 shape: frame.shape,
1627 operation: "smart pointer has no pointee",
1628 });
1629 }
1630 },
1631 _ => {
1632 return Err(ReflectError::OperationFailed {
1633 shape: frame.shape,
1634 operation: "expected smart pointer definition",
1635 });
1636 }
1637 };
1638
1639 crate::trace!("Pointee is a slice of {element_shape}");
1641 let element_layout = match element_shape.layout.sized_layout() {
1642 Ok(layout) => layout,
1643 Err(_) => {
1644 return Err(ReflectError::OperationFailed {
1645 shape: element_shape,
1646 operation: "cannot allocate unsized element",
1647 });
1648 }
1649 };
1650
1651 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1652 let Some(element_ptr) = NonNull::new(element_ptr) else {
1653 return Err(ReflectError::OperationFailed {
1654 shape: frame.shape,
1655 operation: "failed to allocate memory for list element",
1656 });
1657 };
1658
1659 crate::trace!("Pushing element frame, which we just allocated");
1661 let element_frame = Frame::new(
1662 PtrUninit::new(element_ptr),
1663 element_shape,
1664 FrameOwnership::Owned,
1665 );
1666 self.frames.push(element_frame);
1667
1668 let parent_idx = self.frames.len() - 2;
1671 if let Tracker::SmartPointerSlice { building_item, .. } =
1672 &mut self.frames[parent_idx].tracker
1673 {
1674 crate::trace!("Marking element frame as building item");
1675 *building_item = true;
1676 }
1677
1678 return Ok(self);
1679 }
1680
1681 let list_def = match &frame.shape.def {
1683 Def::List(list_def) => list_def,
1684 _ => {
1685 return Err(ReflectError::OperationFailed {
1686 shape: frame.shape,
1687 operation: "push can only be called on List types",
1688 });
1689 }
1690 };
1691
1692 match &mut frame.tracker {
1694 Tracker::List {
1695 is_initialized: true,
1696 current_child,
1697 } => {
1698 if *current_child {
1699 return Err(ReflectError::OperationFailed {
1700 shape: frame.shape,
1701 operation: "already pushing an element, call pop() first",
1702 });
1703 }
1704 *current_child = true;
1705 }
1706 _ => {
1707 return Err(ReflectError::OperationFailed {
1708 shape: frame.shape,
1709 operation: "must call begin_list() before push()",
1710 });
1711 }
1712 }
1713
1714 let element_shape = list_def.t();
1716
1717 let element_layout = match element_shape.layout.sized_layout() {
1719 Ok(layout) => layout,
1720 Err(_) => {
1721 return Err(ReflectError::Unsized {
1722 shape: element_shape,
1723 operation: "begin_list_item: calculating element layout",
1724 });
1725 }
1726 };
1727 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1728
1729 let Some(element_ptr) = NonNull::new(element_ptr) else {
1730 return Err(ReflectError::OperationFailed {
1731 shape: frame.shape,
1732 operation: "failed to allocate memory for list element",
1733 });
1734 };
1735
1736 self.frames.push(Frame::new(
1738 PtrUninit::new(element_ptr),
1739 element_shape,
1740 FrameOwnership::Owned,
1741 ));
1742
1743 Ok(self)
1744 }
1745}
1746
1747impl Partial<'_> {
1751 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1756 self.require_active()?;
1757 let frame = self.frames.last_mut().unwrap();
1758
1759 let map_def = match &frame.shape.def {
1761 Def::Map(map_def) => map_def,
1762 _ => {
1763 return Err(ReflectError::OperationFailed {
1764 shape: frame.shape,
1765 operation: "begin_map can only be called on Map types",
1766 });
1767 }
1768 };
1769
1770 let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1771
1772 unsafe {
1774 init_fn(frame.data, 0);
1775 }
1776
1777 frame.tracker = Tracker::Map {
1779 is_initialized: true,
1780 insert_state: MapInsertState::Idle,
1781 };
1782
1783 Ok(self)
1784 }
1785
1786 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1790 self.require_active()?;
1791 let frame = self.frames.last_mut().unwrap();
1792
1793 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1795 (
1796 Def::Map(map_def),
1797 Tracker::Map {
1798 is_initialized: true,
1799 insert_state,
1800 },
1801 ) => {
1802 match insert_state {
1803 MapInsertState::Idle => {
1804 *insert_state = MapInsertState::PushingKey { key_ptr: None };
1806 }
1807 MapInsertState::PushingKey { key_ptr } => {
1808 if key_ptr.is_some() {
1809 return Err(ReflectError::OperationFailed {
1810 shape: frame.shape,
1811 operation: "already pushing a key, call end() first",
1812 });
1813 }
1814 }
1815 _ => {
1816 return Err(ReflectError::OperationFailed {
1817 shape: frame.shape,
1818 operation: "must complete current operation before begin_key()",
1819 });
1820 }
1821 }
1822 map_def
1823 }
1824 _ => {
1825 return Err(ReflectError::OperationFailed {
1826 shape: frame.shape,
1827 operation: "must call begin_map() before begin_key()",
1828 });
1829 }
1830 };
1831
1832 let key_shape = map_def.k();
1834
1835 let key_layout = match key_shape.layout.sized_layout() {
1837 Ok(layout) => layout,
1838 Err(_) => {
1839 return Err(ReflectError::Unsized {
1840 shape: key_shape,
1841 operation: "begin_key allocating key",
1842 });
1843 }
1844 };
1845 let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1846
1847 let Some(key_ptr_raw) = NonNull::new(key_ptr_raw) else {
1848 return Err(ReflectError::OperationFailed {
1849 shape: frame.shape,
1850 operation: "failed to allocate memory for map key",
1851 });
1852 };
1853
1854 match &mut frame.tracker {
1856 Tracker::Map {
1857 insert_state: MapInsertState::PushingKey { key_ptr: kp },
1858 ..
1859 } => {
1860 *kp = Some(PtrUninit::new(key_ptr_raw));
1861 }
1862 _ => unreachable!(),
1863 }
1864
1865 self.frames.push(Frame::new(
1867 PtrUninit::new(key_ptr_raw),
1868 key_shape,
1869 FrameOwnership::ManagedElsewhere, ));
1871
1872 Ok(self)
1873 }
1874
1875 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1878 self.require_active()?;
1879 let frame = self.frames.last_mut().unwrap();
1880
1881 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1883 (
1884 Def::Map(map_def),
1885 Tracker::Map {
1886 insert_state: MapInsertState::PushingValue { value_ptr, .. },
1887 ..
1888 },
1889 ) => {
1890 if value_ptr.is_some() {
1891 return Err(ReflectError::OperationFailed {
1892 shape: frame.shape,
1893 operation: "already pushing a value, call pop() first",
1894 });
1895 }
1896 map_def
1897 }
1898 _ => {
1899 return Err(ReflectError::OperationFailed {
1900 shape: frame.shape,
1901 operation: "must complete key before push_value()",
1902 });
1903 }
1904 };
1905
1906 let value_shape = map_def.v();
1908
1909 let value_layout = match value_shape.layout.sized_layout() {
1911 Ok(layout) => layout,
1912 Err(_) => {
1913 return Err(ReflectError::Unsized {
1914 shape: value_shape,
1915 operation: "begin_value allocating value",
1916 });
1917 }
1918 };
1919 let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1920
1921 let Some(value_ptr_raw) = NonNull::new(value_ptr_raw) else {
1922 return Err(ReflectError::OperationFailed {
1923 shape: frame.shape,
1924 operation: "failed to allocate memory for map value",
1925 });
1926 };
1927
1928 match &mut frame.tracker {
1930 Tracker::Map {
1931 insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1932 ..
1933 } => {
1934 *vp = Some(PtrUninit::new(value_ptr_raw));
1935 }
1936 _ => unreachable!(),
1937 }
1938
1939 self.frames.push(Frame::new(
1941 PtrUninit::new(value_ptr_raw),
1942 value_shape,
1943 FrameOwnership::ManagedElsewhere, ));
1945
1946 Ok(self)
1947 }
1948}
1949
1950impl Partial<'_> {
1954 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
1956 self.require_active()?;
1957 let frame = self.frames.last_mut().unwrap();
1958
1959 let option_def = match frame.shape.def {
1961 Def::Option(def) => def,
1962 _ => {
1963 return Err(ReflectError::WasNotA {
1964 expected: "Option",
1965 actual: frame.shape,
1966 });
1967 }
1968 };
1969
1970 if matches!(frame.tracker, Tracker::Uninit) {
1972 frame.tracker = Tracker::Option {
1973 building_inner: true,
1974 };
1975 }
1976
1977 let inner_shape = option_def.t;
1979
1980 let inner_layout =
1982 inner_shape
1983 .layout
1984 .sized_layout()
1985 .map_err(|_| ReflectError::Unsized {
1986 shape: inner_shape,
1987 operation: "begin_some, allocating Option inner value",
1988 })?;
1989
1990 let inner_data = if inner_layout.size() == 0 {
1991 PtrUninit::new(NonNull::<u8>::dangling())
1993 } else {
1994 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
1996 let Some(ptr) = NonNull::new(ptr) else {
1997 alloc::alloc::handle_alloc_error(inner_layout);
1998 };
1999 PtrUninit::new(ptr)
2000 };
2001
2002 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
2004 self.frames.push(inner_frame);
2005
2006 Ok(self)
2007 }
2008
2009 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
2011 self.require_active()?;
2012
2013 let (inner_shape, has_try_from, parent_shape) = {
2015 let frame = self.frames.last().unwrap();
2016 if let Some(inner_shape) = frame.shape.inner {
2017 let has_try_from = frame.shape.vtable.try_from.is_some();
2018 (Some(inner_shape), has_try_from, frame.shape)
2019 } else {
2020 (None, false, frame.shape)
2021 }
2022 };
2023
2024 if let Some(inner_shape) = inner_shape {
2025 if has_try_from {
2026 let inner_layout =
2033 inner_shape
2034 .layout
2035 .sized_layout()
2036 .map_err(|_| ReflectError::Unsized {
2037 shape: inner_shape,
2038 operation: "begin_inner, getting inner layout",
2039 })?;
2040
2041 let inner_data = if inner_layout.size() == 0 {
2042 PtrUninit::new(NonNull::<u8>::dangling())
2044 } else {
2045 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2047 let Some(ptr) = NonNull::new(ptr) else {
2048 alloc::alloc::handle_alloc_error(inner_layout);
2049 };
2050 PtrUninit::new(ptr)
2051 };
2052
2053 trace!(
2057 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
2058 );
2059 self.frames
2060 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2061
2062 Ok(self)
2063 } else {
2064 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
2067 self.begin_nth_field(0)
2068 }
2069 } else {
2070 Err(ReflectError::OperationFailed {
2071 shape: parent_shape,
2072 operation: "type does not have an inner value",
2073 })
2074 }
2075 }
2076}
2077
2078impl<'facet> Partial<'facet> {
2082 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2086 where
2087 U: Facet<'facet>,
2088 {
2089 self.begin_nth_field(idx)?.set(value)?.end()
2090 }
2091
2092 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
2094 where
2095 U: Facet<'facet>,
2096 {
2097 self.begin_field(field_name)?.set(value)?.end()
2098 }
2099
2100 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2102 where
2103 U: Facet<'facet>,
2104 {
2105 self.begin_key()?.set(value)?.end()
2106 }
2107
2108 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2110 where
2111 U: Facet<'facet>,
2112 {
2113 self.begin_value()?.set(value)?.end()
2114 }
2115
2116 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2118 where
2119 U: Facet<'facet>,
2120 {
2121 self.begin_list_item()?.set(value)?.end()
2122 }
2123}
2124
2125impl<'facet> Partial<'facet> {
2129 fn select_variant_internal(
2138 &mut self,
2139 enum_type: &EnumType,
2140 variant: &'static Variant,
2141 ) -> Result<(), ReflectError> {
2142 let frame = self.frames.last().unwrap();
2144
2145 match enum_type.enum_repr {
2147 EnumRepr::RustNPO => {
2148 return Err(ReflectError::OperationFailed {
2149 shape: frame.shape,
2150 operation: "RustNPO enums are not supported for incremental building",
2151 });
2152 }
2153 EnumRepr::U8
2154 | EnumRepr::U16
2155 | EnumRepr::U32
2156 | EnumRepr::U64
2157 | EnumRepr::I8
2158 | EnumRepr::I16
2159 | EnumRepr::I32
2160 | EnumRepr::I64
2161 | EnumRepr::USize
2162 | EnumRepr::ISize => {
2163 }
2165 }
2166
2167 let Some(discriminant) = variant.discriminant else {
2168 return Err(ReflectError::OperationFailed {
2169 shape: frame.shape,
2170 operation: "trying to select an enum variant without a discriminant",
2171 });
2172 };
2173
2174 let fr = self.frames.last_mut().unwrap();
2176
2177 unsafe {
2179 match enum_type.enum_repr {
2180 EnumRepr::U8 => {
2181 let ptr = fr.data.as_mut_byte_ptr();
2182 *ptr = discriminant as u8;
2183 }
2184 EnumRepr::U16 => {
2185 let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
2186 *ptr = discriminant as u16;
2187 }
2188 EnumRepr::U32 => {
2189 let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
2190 *ptr = discriminant as u32;
2191 }
2192 EnumRepr::U64 => {
2193 let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
2194 *ptr = discriminant as u64;
2195 }
2196 EnumRepr::I8 => {
2197 let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
2198 *ptr = discriminant as i8;
2199 }
2200 EnumRepr::I16 => {
2201 let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
2202 *ptr = discriminant as i16;
2203 }
2204 EnumRepr::I32 => {
2205 let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
2206 *ptr = discriminant as i32;
2207 }
2208 EnumRepr::I64 => {
2209 let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
2210 *ptr = discriminant;
2211 }
2212 EnumRepr::USize => {
2213 let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
2214 *ptr = discriminant as usize;
2215 }
2216 EnumRepr::ISize => {
2217 let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
2218 *ptr = discriminant as isize;
2219 }
2220 _ => unreachable!("Already checked enum representation above"),
2221 }
2222 }
2223
2224 fr.tracker = Tracker::Enum {
2226 variant,
2227 data: ISet::new(variant.data.fields.len()),
2228 current_child: None,
2229 };
2230
2231 Ok(())
2232 }
2233
2234 fn get_fields(&self) -> Result<&'static [Field], ReflectError> {
2237 let frame = self.frames.last().unwrap();
2238 match frame.shape.ty {
2239 Type::Primitive(_) => Err(ReflectError::OperationFailed {
2240 shape: frame.shape,
2241 operation: "cannot select a field from a primitive type",
2242 }),
2243 Type::Sequence(_) => Err(ReflectError::OperationFailed {
2244 shape: frame.shape,
2245 operation: "cannot select a field from a sequence type",
2246 }),
2247 Type::User(user_type) => match user_type {
2248 UserType::Struct(struct_type) => Ok(struct_type.fields),
2249 UserType::Enum(_) => {
2250 let Tracker::Enum { variant, .. } = &frame.tracker else {
2251 return Err(ReflectError::OperationFailed {
2252 shape: frame.shape,
2253 operation: "must select variant before selecting enum fields",
2254 });
2255 };
2256 Ok(variant.data.fields)
2257 }
2258 UserType::Union(_) => Err(ReflectError::OperationFailed {
2259 shape: frame.shape,
2260 operation: "cannot select a field from a union type",
2261 }),
2262 UserType::Opaque => Err(ReflectError::OperationFailed {
2263 shape: frame.shape,
2264 operation: "opaque types cannot be reflected upon",
2265 }),
2266 },
2267 Type::Pointer(_) => Err(ReflectError::OperationFailed {
2268 shape: frame.shape,
2269 operation: "cannot select a field from a pointer type",
2270 }),
2271 }
2272 }
2273
2274 fn begin_nth_struct_field(
2276 frame: &mut Frame,
2277 struct_type: StructType,
2278 idx: usize,
2279 ) -> Result<Frame, ReflectError> {
2280 if idx >= struct_type.fields.len() {
2281 return Err(ReflectError::OperationFailed {
2282 shape: frame.shape,
2283 operation: "field index out of bounds",
2284 });
2285 }
2286 let field = &struct_type.fields[idx];
2287
2288 if !matches!(frame.tracker, Tracker::Struct { .. }) {
2289 frame.tracker = Tracker::Struct {
2290 iset: ISet::new(struct_type.fields.len()),
2291 current_child: None,
2292 }
2293 }
2294
2295 let was_field_init = match &mut frame.tracker {
2296 Tracker::Struct {
2297 iset,
2298 current_child,
2299 } => {
2300 *current_child = Some(idx);
2301 iset.get(idx)
2302 }
2303 _ => unreachable!(),
2304 };
2305
2306 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2308 let field_shape = field.shape();
2309
2310 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2311 if was_field_init {
2312 unsafe {
2313 next_frame.mark_as_init();
2315 }
2316 }
2317
2318 Ok(next_frame)
2319 }
2320
2321 fn begin_nth_array_element(
2323 frame: &mut Frame,
2324 array_type: ArrayType,
2325 idx: usize,
2326 ) -> Result<Frame, ReflectError> {
2327 if idx >= array_type.n {
2328 return Err(ReflectError::OperationFailed {
2329 shape: frame.shape,
2330 operation: "array index out of bounds",
2331 });
2332 }
2333
2334 if array_type.n > 63 {
2335 return Err(ReflectError::OperationFailed {
2336 shape: frame.shape,
2337 operation: "arrays larger than 63 elements are not yet supported",
2338 });
2339 }
2340
2341 match &frame.tracker {
2343 Tracker::Uninit => {
2344 frame.tracker = Tracker::Array {
2346 iset: ISet::default(),
2347 current_child: None,
2348 };
2349 }
2350 Tracker::Array { .. } => {
2351 }
2353 _other => {
2354 return Err(ReflectError::OperationFailed {
2355 shape: frame.shape,
2356 operation: "unexpected tracker state: expected Uninit or Array",
2357 });
2358 }
2359 }
2360
2361 match &mut frame.tracker {
2362 Tracker::Array {
2363 iset,
2364 current_child,
2365 } => {
2366 *current_child = Some(idx);
2367 let was_field_init = iset.get(idx);
2368
2369 let Ok(element_layout) = array_type.t.layout.sized_layout() else {
2371 return Err(ReflectError::Unsized {
2372 shape: array_type.t,
2373 operation: "begin_nth_element, calculating array element offset",
2374 });
2375 };
2376 let offset = element_layout.size() * idx;
2377 let element_data = unsafe { frame.data.field_uninit_at(offset) };
2378
2379 let mut next_frame = Frame::new(element_data, array_type.t, FrameOwnership::Field);
2380 if was_field_init {
2381 unsafe {
2383 next_frame.mark_as_init();
2384 }
2385 }
2386 Ok(next_frame)
2387 }
2388 _ => unreachable!(),
2389 }
2390 }
2391
2392 fn begin_nth_enum_field(
2394 frame: &mut Frame,
2395 variant: &'static Variant,
2396 idx: usize,
2397 ) -> Result<Frame, ReflectError> {
2398 if idx >= variant.data.fields.len() {
2399 return Err(ReflectError::OperationFailed {
2400 shape: frame.shape,
2401 operation: "enum field index out of bounds",
2402 });
2403 }
2404
2405 let field = &variant.data.fields[idx];
2406
2407 let was_field_init = match &mut frame.tracker {
2409 Tracker::Enum {
2410 data,
2411 current_child,
2412 ..
2413 } => {
2414 *current_child = Some(idx);
2415 data.get(idx)
2416 }
2417 _ => {
2418 return Err(ReflectError::OperationFailed {
2419 shape: frame.shape,
2420 operation: "selecting a field on an enum requires selecting a variant first",
2421 });
2422 }
2423 };
2424
2425 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2428 let field_shape = field.shape();
2429
2430 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2431 if was_field_init {
2432 unsafe {
2434 next_frame.mark_as_init();
2435 }
2436 }
2437
2438 Ok(next_frame)
2439 }
2440
2441 #[inline]
2443 pub(crate) fn require_active(&self) -> Result<(), ReflectError> {
2444 if self.state == PartialState::Active {
2445 Ok(())
2446 } else {
2447 Err(ReflectError::InvariantViolation {
2448 invariant: "Cannot use Partial after it has been built or poisoned",
2449 })
2450 }
2451 }
2452}