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) if smart_ptr_def.constructible_from_pointee() => {
1377 let pointee_shape = match smart_ptr_def.pointee() {
1379 Some(shape) => shape,
1380 None => {
1381 return Err(ReflectError::OperationFailed {
1382 shape: frame.shape,
1383 operation: "Smart pointer must have a pointee shape",
1384 });
1385 }
1386 };
1387
1388 if pointee_shape.layout.sized_layout().is_ok() {
1389 if matches!(frame.tracker, Tracker::Uninit) {
1393 frame.tracker = Tracker::SmartPointer {
1394 is_initialized: false,
1395 };
1396 }
1397
1398 let inner_layout = match pointee_shape.layout.sized_layout() {
1399 Ok(layout) => layout,
1400 Err(_) => {
1401 return Err(ReflectError::Unsized {
1402 shape: pointee_shape,
1403 operation: "begin_smart_ptr, calculating inner value layout",
1404 });
1405 }
1406 };
1407 let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1408 let Some(inner_ptr) = NonNull::new(inner_ptr) else {
1409 return Err(ReflectError::OperationFailed {
1410 shape: frame.shape,
1411 operation: "failed to allocate memory for smart pointer inner value",
1412 });
1413 };
1414
1415 self.frames.push(Frame::new(
1417 PtrUninit::new(inner_ptr),
1418 pointee_shape,
1419 FrameOwnership::Owned,
1420 ));
1421 } else {
1422 if pointee_shape == str::SHAPE {
1424 crate::trace!("Pointee is str");
1425
1426 let string_layout = String::SHAPE
1428 .layout
1429 .sized_layout()
1430 .expect("String must have a sized layout");
1431 let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1432 let Some(string_ptr) = NonNull::new(string_ptr) else {
1433 return Err(ReflectError::OperationFailed {
1434 shape: frame.shape,
1435 operation: "failed to allocate memory for string",
1436 });
1437 };
1438 let mut frame = Frame::new(
1439 PtrUninit::new(string_ptr),
1440 String::SHAPE,
1441 FrameOwnership::Owned,
1442 );
1443 frame.tracker = Tracker::Uninit;
1444 self.frames.push(frame);
1445 } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1446 crate::trace!("Pointee is [{}]", _st.t);
1447
1448 let slice_builder_vtable = smart_ptr_def
1450 .vtable
1451 .slice_builder_vtable
1452 .ok_or(ReflectError::OperationFailed {
1453 shape: frame.shape,
1454 operation: "smart pointer does not support slice building",
1455 })?;
1456
1457 let builder_ptr = (slice_builder_vtable.new_fn)();
1459
1460 if let FrameOwnership::Owned = frame.ownership {
1462 if let Ok(layout) = frame.shape.layout.sized_layout() {
1463 if layout.size() > 0 {
1464 unsafe {
1465 alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1466 };
1467 }
1468 }
1469 }
1470
1471 frame.data = builder_ptr.as_uninit();
1473 frame.tracker = Tracker::SmartPointerSlice {
1474 vtable: slice_builder_vtable,
1475 building_item: false,
1476 };
1477 frame.ownership = FrameOwnership::ManagedElsewhere;
1479 } else {
1480 return Err(ReflectError::OperationFailed {
1481 shape: frame.shape,
1482 operation: "push_smart_ptr can only be called on pointers to supported pointee types",
1483 });
1484 }
1485 }
1486
1487 Ok(self)
1488 }
1489 _ => Err(ReflectError::OperationFailed {
1490 shape: frame.shape,
1491 operation: "push_smart_ptr can only be called on compatible types",
1492 }),
1493 }
1494 }
1495}
1496
1497impl Partial<'_> {
1501 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1509 crate::trace!("begin_list()");
1510 self.require_active()?;
1511 let frame = self.frames.last_mut().unwrap();
1512
1513 match &frame.tracker {
1514 Tracker::Uninit => {
1515 }
1517 Tracker::Init => {
1518 frame.tracker = Tracker::List {
1520 is_initialized: true,
1521 current_child: false,
1522 };
1523 return Ok(self);
1524 }
1525 Tracker::List { is_initialized, .. } => {
1526 if *is_initialized {
1527 return Ok(self);
1529 }
1530 }
1531 Tracker::SmartPointerSlice { .. } => {
1532 return Ok(self);
1534 }
1535 _ => {
1536 return Err(ReflectError::UnexpectedTracker {
1537 message: "begin_list called but tracker isn't something list-like",
1538 current_tracker: frame.tracker.kind(),
1539 });
1540 }
1541 };
1542
1543 let list_def = match &frame.shape.def {
1545 Def::List(list_def) => list_def,
1546 _ => {
1547 return Err(ReflectError::OperationFailed {
1548 shape: frame.shape,
1549 operation: "begin_list can only be called on List types",
1550 });
1551 }
1552 };
1553
1554 let init_fn = match list_def.vtable.init_in_place_with_capacity {
1556 Some(f) => f,
1557 None => {
1558 return Err(ReflectError::OperationFailed {
1559 shape: frame.shape,
1560 operation: "list type does not support initialization with capacity",
1561 });
1562 }
1563 };
1564
1565 unsafe {
1567 init_fn(frame.data, 0);
1568 }
1569
1570 frame.tracker = Tracker::List {
1572 is_initialized: true,
1573 current_child: false,
1574 };
1575
1576 Ok(self)
1577 }
1578
1579 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1582 crate::trace!("begin_list_item()");
1583 self.require_active()?;
1584 let frame = self.frames.last_mut().unwrap();
1585
1586 if let Tracker::SmartPointerSlice {
1588 building_item,
1589 vtable: _,
1590 } = &frame.tracker
1591 {
1592 if *building_item {
1593 return Err(ReflectError::OperationFailed {
1594 shape: frame.shape,
1595 operation: "already building an item, call end() first",
1596 });
1597 }
1598
1599 let element_shape = match &frame.shape.def {
1601 Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1602 Some(pointee_shape) => match &pointee_shape.ty {
1603 Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1604 _ => {
1605 return Err(ReflectError::OperationFailed {
1606 shape: frame.shape,
1607 operation: "smart pointer pointee is not a slice",
1608 });
1609 }
1610 },
1611 None => {
1612 return Err(ReflectError::OperationFailed {
1613 shape: frame.shape,
1614 operation: "smart pointer has no pointee",
1615 });
1616 }
1617 },
1618 _ => {
1619 return Err(ReflectError::OperationFailed {
1620 shape: frame.shape,
1621 operation: "expected smart pointer definition",
1622 });
1623 }
1624 };
1625
1626 crate::trace!("Pointee is a slice of {element_shape}");
1628 let element_layout = match element_shape.layout.sized_layout() {
1629 Ok(layout) => layout,
1630 Err(_) => {
1631 return Err(ReflectError::OperationFailed {
1632 shape: element_shape,
1633 operation: "cannot allocate unsized element",
1634 });
1635 }
1636 };
1637
1638 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1639 let Some(element_ptr) = NonNull::new(element_ptr) else {
1640 return Err(ReflectError::OperationFailed {
1641 shape: frame.shape,
1642 operation: "failed to allocate memory for list element",
1643 });
1644 };
1645
1646 crate::trace!("Pushing element frame, which we just allocated");
1648 let element_frame = Frame::new(
1649 PtrUninit::new(element_ptr),
1650 element_shape,
1651 FrameOwnership::Owned,
1652 );
1653 self.frames.push(element_frame);
1654
1655 let parent_idx = self.frames.len() - 2;
1658 if let Tracker::SmartPointerSlice { building_item, .. } =
1659 &mut self.frames[parent_idx].tracker
1660 {
1661 crate::trace!("Marking element frame as building item");
1662 *building_item = true;
1663 }
1664
1665 return Ok(self);
1666 }
1667
1668 let list_def = match &frame.shape.def {
1670 Def::List(list_def) => list_def,
1671 _ => {
1672 return Err(ReflectError::OperationFailed {
1673 shape: frame.shape,
1674 operation: "push can only be called on List types",
1675 });
1676 }
1677 };
1678
1679 match &mut frame.tracker {
1681 Tracker::List {
1682 is_initialized: true,
1683 current_child,
1684 } => {
1685 if *current_child {
1686 return Err(ReflectError::OperationFailed {
1687 shape: frame.shape,
1688 operation: "already pushing an element, call pop() first",
1689 });
1690 }
1691 *current_child = true;
1692 }
1693 _ => {
1694 return Err(ReflectError::OperationFailed {
1695 shape: frame.shape,
1696 operation: "must call begin_list() before push()",
1697 });
1698 }
1699 }
1700
1701 let element_shape = list_def.t();
1703
1704 let element_layout = match element_shape.layout.sized_layout() {
1706 Ok(layout) => layout,
1707 Err(_) => {
1708 return Err(ReflectError::Unsized {
1709 shape: element_shape,
1710 operation: "begin_list_item: calculating element layout",
1711 });
1712 }
1713 };
1714 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1715
1716 let Some(element_ptr) = NonNull::new(element_ptr) else {
1717 return Err(ReflectError::OperationFailed {
1718 shape: frame.shape,
1719 operation: "failed to allocate memory for list element",
1720 });
1721 };
1722
1723 self.frames.push(Frame::new(
1725 PtrUninit::new(element_ptr),
1726 element_shape,
1727 FrameOwnership::Owned,
1728 ));
1729
1730 Ok(self)
1731 }
1732}
1733
1734impl Partial<'_> {
1738 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1743 self.require_active()?;
1744 let frame = self.frames.last_mut().unwrap();
1745
1746 let map_def = match &frame.shape.def {
1748 Def::Map(map_def) => map_def,
1749 _ => {
1750 return Err(ReflectError::OperationFailed {
1751 shape: frame.shape,
1752 operation: "begin_map can only be called on Map types",
1753 });
1754 }
1755 };
1756
1757 let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1758
1759 unsafe {
1761 init_fn(frame.data, 0);
1762 }
1763
1764 frame.tracker = Tracker::Map {
1766 is_initialized: true,
1767 insert_state: MapInsertState::Idle,
1768 };
1769
1770 Ok(self)
1771 }
1772
1773 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1777 self.require_active()?;
1778 let frame = self.frames.last_mut().unwrap();
1779
1780 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1782 (
1783 Def::Map(map_def),
1784 Tracker::Map {
1785 is_initialized: true,
1786 insert_state,
1787 },
1788 ) => {
1789 match insert_state {
1790 MapInsertState::Idle => {
1791 *insert_state = MapInsertState::PushingKey { key_ptr: None };
1793 }
1794 MapInsertState::PushingKey { key_ptr } => {
1795 if key_ptr.is_some() {
1796 return Err(ReflectError::OperationFailed {
1797 shape: frame.shape,
1798 operation: "already pushing a key, call end() first",
1799 });
1800 }
1801 }
1802 _ => {
1803 return Err(ReflectError::OperationFailed {
1804 shape: frame.shape,
1805 operation: "must complete current operation before begin_key()",
1806 });
1807 }
1808 }
1809 map_def
1810 }
1811 _ => {
1812 return Err(ReflectError::OperationFailed {
1813 shape: frame.shape,
1814 operation: "must call begin_map() before begin_key()",
1815 });
1816 }
1817 };
1818
1819 let key_shape = map_def.k();
1821
1822 let key_layout = match key_shape.layout.sized_layout() {
1824 Ok(layout) => layout,
1825 Err(_) => {
1826 return Err(ReflectError::Unsized {
1827 shape: key_shape,
1828 operation: "begin_key allocating key",
1829 });
1830 }
1831 };
1832 let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1833
1834 let Some(key_ptr_raw) = NonNull::new(key_ptr_raw) else {
1835 return Err(ReflectError::OperationFailed {
1836 shape: frame.shape,
1837 operation: "failed to allocate memory for map key",
1838 });
1839 };
1840
1841 match &mut frame.tracker {
1843 Tracker::Map {
1844 insert_state: MapInsertState::PushingKey { key_ptr: kp },
1845 ..
1846 } => {
1847 *kp = Some(PtrUninit::new(key_ptr_raw));
1848 }
1849 _ => unreachable!(),
1850 }
1851
1852 self.frames.push(Frame::new(
1854 PtrUninit::new(key_ptr_raw),
1855 key_shape,
1856 FrameOwnership::ManagedElsewhere, ));
1858
1859 Ok(self)
1860 }
1861
1862 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1865 self.require_active()?;
1866 let frame = self.frames.last_mut().unwrap();
1867
1868 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1870 (
1871 Def::Map(map_def),
1872 Tracker::Map {
1873 insert_state: MapInsertState::PushingValue { value_ptr, .. },
1874 ..
1875 },
1876 ) => {
1877 if value_ptr.is_some() {
1878 return Err(ReflectError::OperationFailed {
1879 shape: frame.shape,
1880 operation: "already pushing a value, call pop() first",
1881 });
1882 }
1883 map_def
1884 }
1885 _ => {
1886 return Err(ReflectError::OperationFailed {
1887 shape: frame.shape,
1888 operation: "must complete key before push_value()",
1889 });
1890 }
1891 };
1892
1893 let value_shape = map_def.v();
1895
1896 let value_layout = match value_shape.layout.sized_layout() {
1898 Ok(layout) => layout,
1899 Err(_) => {
1900 return Err(ReflectError::Unsized {
1901 shape: value_shape,
1902 operation: "begin_value allocating value",
1903 });
1904 }
1905 };
1906 let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1907
1908 let Some(value_ptr_raw) = NonNull::new(value_ptr_raw) else {
1909 return Err(ReflectError::OperationFailed {
1910 shape: frame.shape,
1911 operation: "failed to allocate memory for map value",
1912 });
1913 };
1914
1915 match &mut frame.tracker {
1917 Tracker::Map {
1918 insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1919 ..
1920 } => {
1921 *vp = Some(PtrUninit::new(value_ptr_raw));
1922 }
1923 _ => unreachable!(),
1924 }
1925
1926 self.frames.push(Frame::new(
1928 PtrUninit::new(value_ptr_raw),
1929 value_shape,
1930 FrameOwnership::ManagedElsewhere, ));
1932
1933 Ok(self)
1934 }
1935}
1936
1937impl Partial<'_> {
1941 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
1943 self.require_active()?;
1944 let frame = self.frames.last_mut().unwrap();
1945
1946 let option_def = match frame.shape.def {
1948 Def::Option(def) => def,
1949 _ => {
1950 return Err(ReflectError::WasNotA {
1951 expected: "Option",
1952 actual: frame.shape,
1953 });
1954 }
1955 };
1956
1957 if matches!(frame.tracker, Tracker::Uninit) {
1959 frame.tracker = Tracker::Option {
1960 building_inner: true,
1961 };
1962 }
1963
1964 let inner_shape = option_def.t;
1966
1967 let inner_layout =
1969 inner_shape
1970 .layout
1971 .sized_layout()
1972 .map_err(|_| ReflectError::Unsized {
1973 shape: inner_shape,
1974 operation: "begin_some, allocating Option inner value",
1975 })?;
1976
1977 let inner_data = if inner_layout.size() == 0 {
1978 PtrUninit::new(NonNull::<u8>::dangling())
1980 } else {
1981 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
1983 let Some(ptr) = NonNull::new(ptr) else {
1984 alloc::alloc::handle_alloc_error(inner_layout);
1985 };
1986 PtrUninit::new(ptr)
1987 };
1988
1989 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
1991 self.frames.push(inner_frame);
1992
1993 Ok(self)
1994 }
1995
1996 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
1998 self.require_active()?;
1999
2000 let (inner_shape, has_try_from, parent_shape) = {
2002 let frame = self.frames.last().unwrap();
2003 if let Some(inner_shape) = frame.shape.inner {
2004 let has_try_from = frame.shape.vtable.try_from.is_some();
2005 (Some(inner_shape), has_try_from, frame.shape)
2006 } else {
2007 (None, false, frame.shape)
2008 }
2009 };
2010
2011 if let Some(inner_shape) = inner_shape {
2012 if has_try_from {
2013 let inner_layout =
2020 inner_shape
2021 .layout
2022 .sized_layout()
2023 .map_err(|_| ReflectError::Unsized {
2024 shape: inner_shape,
2025 operation: "begin_inner, getting inner layout",
2026 })?;
2027
2028 let inner_data = if inner_layout.size() == 0 {
2029 PtrUninit::new(NonNull::<u8>::dangling())
2031 } else {
2032 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2034 let Some(ptr) = NonNull::new(ptr) else {
2035 alloc::alloc::handle_alloc_error(inner_layout);
2036 };
2037 PtrUninit::new(ptr)
2038 };
2039
2040 trace!(
2044 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
2045 );
2046 self.frames
2047 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2048
2049 Ok(self)
2050 } else {
2051 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
2054 self.begin_nth_field(0)
2055 }
2056 } else {
2057 Err(ReflectError::OperationFailed {
2058 shape: parent_shape,
2059 operation: "type does not have an inner value",
2060 })
2061 }
2062 }
2063}
2064
2065impl<'facet> Partial<'facet> {
2069 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2073 where
2074 U: Facet<'facet>,
2075 {
2076 self.begin_nth_field(idx)?.set(value)?.end()
2077 }
2078
2079 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
2081 where
2082 U: Facet<'facet>,
2083 {
2084 self.begin_field(field_name)?.set(value)?.end()
2085 }
2086
2087 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2089 where
2090 U: Facet<'facet>,
2091 {
2092 self.begin_key()?.set(value)?.end()
2093 }
2094
2095 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2097 where
2098 U: Facet<'facet>,
2099 {
2100 self.begin_value()?.set(value)?.end()
2101 }
2102
2103 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2105 where
2106 U: Facet<'facet>,
2107 {
2108 self.begin_list_item()?.set(value)?.end()
2109 }
2110}
2111
2112impl<'facet> Partial<'facet> {
2116 fn select_variant_internal(
2125 &mut self,
2126 enum_type: &EnumType,
2127 variant: &'static Variant,
2128 ) -> Result<(), ReflectError> {
2129 let frame = self.frames.last().unwrap();
2131
2132 match enum_type.enum_repr {
2134 EnumRepr::RustNPO => {
2135 return Err(ReflectError::OperationFailed {
2136 shape: frame.shape,
2137 operation: "RustNPO enums are not supported for incremental building",
2138 });
2139 }
2140 EnumRepr::U8
2141 | EnumRepr::U16
2142 | EnumRepr::U32
2143 | EnumRepr::U64
2144 | EnumRepr::I8
2145 | EnumRepr::I16
2146 | EnumRepr::I32
2147 | EnumRepr::I64
2148 | EnumRepr::USize
2149 | EnumRepr::ISize => {
2150 }
2152 }
2153
2154 let Some(discriminant) = variant.discriminant else {
2155 return Err(ReflectError::OperationFailed {
2156 shape: frame.shape,
2157 operation: "trying to select an enum variant without a discriminant",
2158 });
2159 };
2160
2161 let fr = self.frames.last_mut().unwrap();
2163
2164 unsafe {
2166 match enum_type.enum_repr {
2167 EnumRepr::U8 => {
2168 let ptr = fr.data.as_mut_byte_ptr();
2169 *ptr = discriminant as u8;
2170 }
2171 EnumRepr::U16 => {
2172 let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
2173 *ptr = discriminant as u16;
2174 }
2175 EnumRepr::U32 => {
2176 let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
2177 *ptr = discriminant as u32;
2178 }
2179 EnumRepr::U64 => {
2180 let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
2181 *ptr = discriminant as u64;
2182 }
2183 EnumRepr::I8 => {
2184 let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
2185 *ptr = discriminant as i8;
2186 }
2187 EnumRepr::I16 => {
2188 let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
2189 *ptr = discriminant as i16;
2190 }
2191 EnumRepr::I32 => {
2192 let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
2193 *ptr = discriminant as i32;
2194 }
2195 EnumRepr::I64 => {
2196 let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
2197 *ptr = discriminant;
2198 }
2199 EnumRepr::USize => {
2200 let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
2201 *ptr = discriminant as usize;
2202 }
2203 EnumRepr::ISize => {
2204 let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
2205 *ptr = discriminant as isize;
2206 }
2207 _ => unreachable!("Already checked enum representation above"),
2208 }
2209 }
2210
2211 fr.tracker = Tracker::Enum {
2213 variant,
2214 data: ISet::new(variant.data.fields.len()),
2215 current_child: None,
2216 };
2217
2218 Ok(())
2219 }
2220
2221 fn get_fields(&self) -> Result<&'static [Field], ReflectError> {
2224 let frame = self.frames.last().unwrap();
2225 match frame.shape.ty {
2226 Type::Primitive(_) => Err(ReflectError::OperationFailed {
2227 shape: frame.shape,
2228 operation: "cannot select a field from a primitive type",
2229 }),
2230 Type::Sequence(_) => Err(ReflectError::OperationFailed {
2231 shape: frame.shape,
2232 operation: "cannot select a field from a sequence type",
2233 }),
2234 Type::User(user_type) => match user_type {
2235 UserType::Struct(struct_type) => Ok(struct_type.fields),
2236 UserType::Enum(_) => {
2237 let Tracker::Enum { variant, .. } = &frame.tracker else {
2238 return Err(ReflectError::OperationFailed {
2239 shape: frame.shape,
2240 operation: "must select variant before selecting enum fields",
2241 });
2242 };
2243 Ok(variant.data.fields)
2244 }
2245 UserType::Union(_) => Err(ReflectError::OperationFailed {
2246 shape: frame.shape,
2247 operation: "cannot select a field from a union type",
2248 }),
2249 UserType::Opaque => Err(ReflectError::OperationFailed {
2250 shape: frame.shape,
2251 operation: "opaque types cannot be reflected upon",
2252 }),
2253 },
2254 Type::Pointer(_) => Err(ReflectError::OperationFailed {
2255 shape: frame.shape,
2256 operation: "cannot select a field from a pointer type",
2257 }),
2258 }
2259 }
2260
2261 fn begin_nth_struct_field(
2263 frame: &mut Frame,
2264 struct_type: StructType,
2265 idx: usize,
2266 ) -> Result<Frame, ReflectError> {
2267 if idx >= struct_type.fields.len() {
2268 return Err(ReflectError::OperationFailed {
2269 shape: frame.shape,
2270 operation: "field index out of bounds",
2271 });
2272 }
2273 let field = &struct_type.fields[idx];
2274
2275 if !matches!(frame.tracker, Tracker::Struct { .. }) {
2276 frame.tracker = Tracker::Struct {
2277 iset: ISet::new(struct_type.fields.len()),
2278 current_child: None,
2279 }
2280 }
2281
2282 let was_field_init = match &mut frame.tracker {
2283 Tracker::Struct {
2284 iset,
2285 current_child,
2286 } => {
2287 *current_child = Some(idx);
2288 iset.get(idx)
2289 }
2290 _ => unreachable!(),
2291 };
2292
2293 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2295 let field_shape = field.shape();
2296
2297 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2298 if was_field_init {
2299 unsafe {
2300 next_frame.mark_as_init();
2302 }
2303 }
2304
2305 Ok(next_frame)
2306 }
2307
2308 fn begin_nth_array_element(
2310 frame: &mut Frame,
2311 array_type: ArrayType,
2312 idx: usize,
2313 ) -> Result<Frame, ReflectError> {
2314 if idx >= array_type.n {
2315 return Err(ReflectError::OperationFailed {
2316 shape: frame.shape,
2317 operation: "array index out of bounds",
2318 });
2319 }
2320
2321 if array_type.n > 63 {
2322 return Err(ReflectError::OperationFailed {
2323 shape: frame.shape,
2324 operation: "arrays larger than 63 elements are not yet supported",
2325 });
2326 }
2327
2328 match &frame.tracker {
2330 Tracker::Uninit => {
2331 frame.tracker = Tracker::Array {
2333 iset: ISet::default(),
2334 current_child: None,
2335 };
2336 }
2337 Tracker::Array { .. } => {
2338 }
2340 _other => {
2341 return Err(ReflectError::OperationFailed {
2342 shape: frame.shape,
2343 operation: "unexpected tracker state: expected Uninit or Array",
2344 });
2345 }
2346 }
2347
2348 match &mut frame.tracker {
2349 Tracker::Array {
2350 iset,
2351 current_child,
2352 } => {
2353 *current_child = Some(idx);
2354 let was_field_init = iset.get(idx);
2355
2356 let Ok(element_layout) = array_type.t.layout.sized_layout() else {
2358 return Err(ReflectError::Unsized {
2359 shape: array_type.t,
2360 operation: "begin_nth_element, calculating array element offset",
2361 });
2362 };
2363 let offset = element_layout.size() * idx;
2364 let element_data = unsafe { frame.data.field_uninit_at(offset) };
2365
2366 let mut next_frame = Frame::new(element_data, array_type.t, FrameOwnership::Field);
2367 if was_field_init {
2368 unsafe {
2370 next_frame.mark_as_init();
2371 }
2372 }
2373 Ok(next_frame)
2374 }
2375 _ => unreachable!(),
2376 }
2377 }
2378
2379 fn begin_nth_enum_field(
2381 frame: &mut Frame,
2382 variant: &'static Variant,
2383 idx: usize,
2384 ) -> Result<Frame, ReflectError> {
2385 if idx >= variant.data.fields.len() {
2386 return Err(ReflectError::OperationFailed {
2387 shape: frame.shape,
2388 operation: "enum field index out of bounds",
2389 });
2390 }
2391
2392 let field = &variant.data.fields[idx];
2393
2394 let was_field_init = match &mut frame.tracker {
2396 Tracker::Enum {
2397 data,
2398 current_child,
2399 ..
2400 } => {
2401 *current_child = Some(idx);
2402 data.get(idx)
2403 }
2404 _ => {
2405 return Err(ReflectError::OperationFailed {
2406 shape: frame.shape,
2407 operation: "selecting a field on an enum requires selecting a variant first",
2408 });
2409 }
2410 };
2411
2412 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2415 let field_shape = field.shape();
2416
2417 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2418 if was_field_init {
2419 unsafe {
2421 next_frame.mark_as_init();
2422 }
2423 }
2424
2425 Ok(next_frame)
2426 }
2427
2428 #[inline]
2430 pub(crate) fn require_active(&self) -> Result<(), ReflectError> {
2431 if self.state == PartialState::Active {
2432 Ok(())
2433 } else {
2434 Err(ReflectError::InvariantViolation {
2435 invariant: "Cannot use Partial after it has been built or poisoned",
2436 })
2437 }
2438 }
2439}