1#[cfg(test)]
110mod tests;
111
112use alloc::boxed::Box;
113use alloc::format;
114use alloc::string::{String, ToString};
115use alloc::vec;
116
117mod iset;
118
119use crate::{Peek, ReflectError, TrackerKind, trace};
120use facet_core::{DefaultInPlaceFn, SequenceType};
121
122use core::marker::PhantomData;
123
124mod heap_value;
125use alloc::vec::Vec;
126pub use heap_value::*;
127
128use facet_core::{
129 Def, EnumRepr, Facet, KnownPointer, PtrConst, PtrMut, PtrUninit, Shape, SliceBuilderVTable,
130 Type, UserType, Variant,
131};
132use iset::ISet;
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136enum PartialState {
137 Active,
139 Built,
141 BuildFailed,
143}
144
145pub struct Partial<'facet> {
152 frames: Vec<Frame>,
154
155 state: PartialState,
157
158 invariant: PhantomData<fn(&'facet ()) -> &'facet ()>,
159}
160
161#[derive(Clone, Copy, Debug)]
162enum MapInsertState {
163 Idle,
165 PushingKey {
167 key_ptr: Option<PtrUninit<'static>>,
169 },
170 PushingValue {
172 key_ptr: PtrUninit<'static>,
174 value_ptr: Option<PtrUninit<'static>>,
176 },
177}
178
179#[derive(Debug)]
180enum FrameOwnership {
181 Owned,
183 Field,
185 ManagedElsewhere,
187}
188
189struct Frame {
190 data: PtrUninit<'static>,
192
193 shape: &'static Shape,
195
196 tracker: Tracker,
198
199 ownership: FrameOwnership,
201}
202
203#[derive(Debug)]
204enum Tracker {
205 Uninit,
207
208 Init,
210
211 Array {
213 iset: ISet,
215 current_child: Option<usize>,
217 },
218
219 Struct {
221 iset: ISet,
224
225 current_child: Option<usize>,
228 },
229
230 SmartPointer {
232 is_initialized: bool,
234 },
235
236 SmartPointerStr {
240 is_initialized: bool,
242 },
243
244 SmartPointerSlice {
248 vtable: &'static SliceBuilderVTable,
250 building_item: bool,
252 },
253
254 Enum {
256 variant: &'static Variant,
257 data: ISet,
258 current_child: Option<usize>,
260 },
261
262 List {
264 is_initialized: bool,
266 current_child: bool,
268 },
269
270 Map {
272 is_initialized: bool,
274 insert_state: MapInsertState,
276 },
277
278 Option {
280 building_inner: bool,
282 },
283}
284
285impl Tracker {
286 fn kind(&self) -> TrackerKind {
287 match self {
288 Tracker::Uninit => TrackerKind::Uninit,
289 Tracker::Init => TrackerKind::Init,
290 Tracker::Array { .. } => TrackerKind::Array,
291 Tracker::Struct { .. } => TrackerKind::Struct,
292 Tracker::SmartPointer { .. } => TrackerKind::SmartPointer,
293 Tracker::SmartPointerStr { .. } => TrackerKind::SmartPointerStr,
294 Tracker::SmartPointerSlice { .. } => TrackerKind::SmartPointerSlice,
295 Tracker::Enum { .. } => TrackerKind::Enum,
296 Tracker::List { .. } => TrackerKind::List,
297 Tracker::Map { .. } => TrackerKind::Map,
298 Tracker::Option { .. } => TrackerKind::Option,
299 }
300 }
301}
302
303impl Frame {
304 fn new(data: PtrUninit<'static>, shape: &'static Shape, ownership: FrameOwnership) -> Self {
305 let tracker = match shape.ty {
308 Type::User(UserType::Struct(struct_type)) if struct_type.fields.is_empty() => {
309 Tracker::Init
310 }
311 _ => Tracker::Uninit,
312 };
313
314 Self {
315 data,
316 shape,
317 tracker,
318 ownership,
319 }
320 }
321
322 fn require_full_initialization(&self) -> Result<(), ReflectError> {
324 match self.tracker {
325 Tracker::Uninit => Err(ReflectError::UninitializedValue { shape: self.shape }),
326 Tracker::Init => Ok(()),
327 Tracker::Array { iset, .. } => {
328 match self.shape.ty {
329 Type::Sequence(facet_core::SequenceType::Array(array_def)) => {
330 if (0..array_def.n).all(|idx| iset.get(idx)) {
332 Ok(())
333 } else {
334 Err(ReflectError::UninitializedValue { shape: self.shape })
335 }
336 }
337 _ => Err(ReflectError::UninitializedValue { shape: self.shape }),
338 }
339 }
340 Tracker::Struct { iset, .. } => {
341 if iset.all_set() {
342 Ok(())
343 } else {
344 match self.shape.ty {
346 Type::User(UserType::Struct(struct_type)) => {
347 let first_missing_idx =
349 (0..struct_type.fields.len()).find(|&idx| !iset.get(idx));
350 if let Some(missing_idx) = first_missing_idx {
351 let field_name = struct_type.fields[missing_idx].name;
352 Err(ReflectError::UninitializedField {
353 shape: self.shape,
354 field_name,
355 })
356 } else {
357 Err(ReflectError::UninitializedValue { shape: self.shape })
359 }
360 }
361 _ => Err(ReflectError::UninitializedValue { shape: self.shape }),
362 }
363 }
364 }
365 Tracker::Enum { variant, data, .. } => {
366 let num_fields = variant.data.fields.len();
368 if num_fields == 0 {
369 Ok(())
371 } else if (0..num_fields).all(|idx| data.get(idx)) {
372 Ok(())
373 } else {
374 let first_missing_idx = (0..num_fields).find(|&idx| !data.get(idx));
376 if let Some(missing_idx) = first_missing_idx {
377 let field_name = variant.data.fields[missing_idx].name;
378 Err(ReflectError::UninitializedEnumField {
379 shape: self.shape,
380 field_name,
381 variant_name: variant.name,
382 })
383 } else {
384 Err(ReflectError::UninitializedValue { shape: self.shape })
385 }
386 }
387 }
388 Tracker::SmartPointer { is_initialized } => {
389 if is_initialized {
390 Ok(())
391 } else {
392 Err(ReflectError::UninitializedValue { shape: self.shape })
393 }
394 }
395 Tracker::SmartPointerStr { is_initialized } => {
396 if is_initialized {
397 Ok(())
398 } else {
399 Err(ReflectError::UninitializedValue { shape: self.shape })
400 }
401 }
402 Tracker::SmartPointerSlice { building_item, .. } => {
403 if building_item {
404 Err(ReflectError::UninitializedValue { shape: self.shape })
405 } else {
406 Ok(())
407 }
408 }
409 Tracker::List { is_initialized, .. } => {
410 if is_initialized {
411 Ok(())
412 } else {
413 Err(ReflectError::UninitializedValue { shape: self.shape })
414 }
415 }
416 Tracker::Map {
417 is_initialized,
418 insert_state,
419 } => {
420 if is_initialized && matches!(insert_state, MapInsertState::Idle) {
421 Ok(())
422 } else {
423 Err(ReflectError::UninitializedValue { shape: self.shape })
424 }
425 }
426 Tracker::Option { building_inner } => {
427 if building_inner {
428 Err(ReflectError::UninitializedValue { shape: self.shape })
429 } else {
430 Ok(())
431 }
432 }
433 }
434 }
435}
436
437impl<'facet> Partial<'facet> {
438 pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
440 crate::trace!(
441 "alloc_shape({:?}), with layout {:?}",
442 shape,
443 shape.layout.sized_layout()
444 );
445
446 let data = shape.allocate().map_err(|_| ReflectError::Unsized {
447 shape,
448 operation: "alloc_shape",
449 })?;
450
451 let mut frames = Vec::with_capacity(4);
455 frames.push(Frame::new(data, shape, FrameOwnership::Owned));
456
457 Ok(Self {
458 frames,
459 state: PartialState::Active,
460 invariant: PhantomData,
461 })
462 }
463
464 pub fn alloc<T>() -> Result<TypedPartial<'facet, T>, ReflectError>
466 where
467 T: Facet<'facet>,
468 {
469 Ok(TypedPartial {
470 inner: Self::alloc_shape(T::SHAPE)?,
471 phantom: PhantomData,
472 })
473 }
474
475 pub fn from_ptr(data: PtrUninit<'_>, shape: &'static Shape) -> Self {
477 let data_static = PtrUninit::new(data.as_mut_byte_ptr());
480 Self {
481 frames: vec![Frame::new(data_static, shape, FrameOwnership::Field)],
482 state: PartialState::Active,
483 invariant: PhantomData,
484 }
485 }
486
487 fn require_active(&self) -> Result<(), ReflectError> {
489 if self.state == PartialState::Active {
490 Ok(())
491 } else {
492 Err(ReflectError::InvariantViolation {
493 invariant: "Cannot use Partial after it has been built or poisoned",
494 })
495 }
496 }
497
498 #[inline]
500 pub fn frame_count(&self) -> usize {
501 self.frames.len()
502 }
503
504 pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
506 where
507 U: Facet<'facet>,
508 {
509 self.require_active()?;
510
511 let ptr_const = PtrConst::new(&raw const value);
514 unsafe {
515 self.set_shape(ptr_const, U::SHAPE)?
517 };
518
519 core::mem::forget(value);
521 Ok(self)
522 }
523
524 #[inline]
540 pub unsafe fn set_shape(
541 &mut self,
542 src_value: PtrConst<'_>,
543 src_shape: &'static Shape,
544 ) -> Result<&mut Self, ReflectError> {
545 self.require_active()?;
546
547 let fr = self.frames.last_mut().unwrap();
548 crate::trace!("set_shape({src_shape:?})");
549 if !fr.shape.is_shape(src_shape) {
550 let err = ReflectError::WrongShape {
551 expected: fr.shape,
552 actual: src_shape,
553 };
554 return Err(err);
555 }
556
557 if fr.shape.layout.sized_layout().is_err() {
558 return Err(ReflectError::Unsized {
559 shape: fr.shape,
560 operation: "set_shape",
561 });
562 }
563
564 let mut need_drop = false;
565 match fr.tracker {
566 Tracker::Uninit => {
567 }
569 Tracker::Init => {
570 need_drop = true;
571 }
572 Tracker::Array { .. } => {
573 todo!("deinitializing select array fields on set_shape is not implemented yet")
574 }
575 Tracker::Struct { .. } => {
576 todo!("deinitializing select struct fields on set_shape is not implemented yet")
577 }
578 Tracker::SmartPointer { is_initialized } => need_drop = is_initialized,
579 Tracker::SmartPointerStr { is_initialized } => need_drop = is_initialized,
580 Tracker::SmartPointerSlice { .. } => {
581 todo!("deinitializing smart pointer str on set_shape is not implemented yet")
582 }
583 Tracker::Enum { .. } => {
584 todo!("deinitializing select enum fields on set_shape is not implemented yet")
587 }
588 Tracker::List { is_initialized, .. } => need_drop = is_initialized,
589 Tracker::Map { is_initialized, .. } => need_drop = is_initialized,
590 Tracker::Option { .. } => todo!(),
591 }
592
593 if need_drop {
594 let drop_in_place = (fr.shape.vtable.sized().unwrap().drop_in_place)();
595 crate::trace!(
596 "set_shape: should drop first (has drop? {:?})",
597 drop_in_place.is_some()
598 );
599
600 if let Some(drop_in_place) = drop_in_place {
601 unsafe {
602 (drop_in_place)(fr.data.assume_init());
603 }
604 }
605 }
606
607 unsafe {
608 fr.data.copy_from(src_value, fr.shape).unwrap();
609 }
610
611 match &mut fr.tracker {
612 Tracker::SmartPointerStr { is_initialized } => {
613 *is_initialized = true;
614 }
615 _ => {
616 fr.tracker = Tracker::Init;
617 }
618 }
619
620 Ok(self)
621 }
622
623 #[inline]
625 pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
626 let frame = self.frames.last().unwrap(); if let Some(default_fn) = frame
629 .shape
630 .vtable
631 .sized()
632 .and_then(|v| (v.default_in_place)())
633 {
634 self.set_from_function(move |ptr: PtrUninit<'_>| {
641 unsafe { default_fn(PtrUninit::new(ptr.as_mut_byte_ptr())) };
642 Ok(())
643 })
644 } else {
645 Err(ReflectError::OperationFailed {
647 shape: frame.shape,
648 operation: "type does not implement Default",
649 })
650 }
651 }
652
653 #[inline]
655 pub fn set_field_default(
656 &mut self,
657 field_default_fn: DefaultInPlaceFn,
658 ) -> Result<&mut Self, ReflectError> {
659 self.set_from_function(move |ptr: PtrUninit<'_>| {
666 unsafe { field_default_fn(PtrUninit::new(ptr.as_mut_byte_ptr())) };
667 Ok(())
668 })
669 }
670
671 pub fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
673 where
674 F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
675 {
676 self.require_active()?;
677
678 let frame = self.frames.last_mut().unwrap();
679
680 if matches!(frame.tracker, Tracker::Init) {
682 if let Some(drop_fn) = frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)()) {
683 unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
684 }
685 }
686
687 if matches!(
689 frame.tracker,
690 Tracker::Option {
691 building_inner: true
692 }
693 ) {
694 return Err(ReflectError::OperationFailed {
695 shape: frame.shape,
696 operation: "Cannot overwrite while building Option inner value",
697 });
698 }
699
700 match f(frame.data) {
702 Ok(()) => {
703 frame.tracker = Tracker::Init;
705 Ok(self)
706 }
707 Err(e) => Err(e),
708 }
709 }
710
711 pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
713 self.require_active()?;
714
715 let frame = self.frames.last_mut().unwrap();
716
717 let parse_fn = match frame.shape.vtable.sized().and_then(|v| (v.parse)()) {
719 Some(parse_fn) => parse_fn,
720 None => {
721 return Err(ReflectError::OperationFailed {
722 shape: frame.shape,
723 operation: "Type does not support parsing from string",
724 });
725 }
726 };
727
728 if matches!(frame.tracker, Tracker::Init) {
730 if let Some(drop_fn) = frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)()) {
731 unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
732 }
733 }
734
735 if matches!(
737 frame.tracker,
738 Tracker::Option {
739 building_inner: true
740 }
741 ) {
742 return Err(ReflectError::OperationFailed {
743 shape: frame.shape,
744 operation: "Cannot overwrite while building Option inner value",
745 });
746 }
747
748 let result = unsafe { parse_fn(s, frame.data) };
750 match result {
751 Ok(_) => {
752 frame.tracker = Tracker::Init;
753 Ok(self)
754 }
755 Err(_parse_error) => Err(ReflectError::OperationFailed {
756 shape: frame.shape,
757 operation: "Failed to parse string value",
758 }),
759 }
760 }
761
762 pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
764 self.require_active()?;
765
766 let fr = self.frames.last_mut().unwrap();
767
768 let enum_type = match fr.shape.ty {
770 Type::User(UserType::Enum(e)) => e,
771 _ => {
772 return Err(ReflectError::OperationFailed {
773 shape: fr.shape,
774 operation: "push_variant_named requires an enum type",
775 });
776 }
777 };
778
779 let variant = match enum_type.variants.iter().find(|v| v.name == variant_name) {
781 Some(v) => v,
782 None => {
783 return Err(ReflectError::OperationFailed {
784 shape: fr.shape,
785 operation: "No variant found with the given name",
786 });
787 }
788 };
789
790 let discriminant = match variant.discriminant {
792 Some(d) => d,
793 None => {
794 return Err(ReflectError::OperationFailed {
795 shape: fr.shape,
796 operation: "Variant has no discriminant value",
797 });
798 }
799 };
800
801 self.select_variant(discriminant)
803 }
804
805 pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
807 self.require_active()?;
808
809 let fr = self.frames.last().unwrap();
811
812 let enum_type = match fr.shape.ty {
814 Type::User(UserType::Enum(e)) => e,
815 _ => {
816 return Err(ReflectError::WasNotA {
817 expected: "enum",
818 actual: fr.shape,
819 });
820 }
821 };
822
823 let variant = match enum_type
825 .variants
826 .iter()
827 .find(|v| v.discriminant == Some(discriminant))
828 {
829 Some(v) => v,
830 None => {
831 return Err(ReflectError::OperationFailed {
832 shape: fr.shape,
833 operation: "No variant found with the given discriminant",
834 });
835 }
836 };
837
838 match enum_type.enum_repr {
840 EnumRepr::RustNPO => {
841 return Err(ReflectError::OperationFailed {
842 shape: fr.shape,
843 operation: "RustNPO enums are not supported for incremental building",
844 });
845 }
846 EnumRepr::U8
847 | EnumRepr::U16
848 | EnumRepr::U32
849 | EnumRepr::U64
850 | EnumRepr::I8
851 | EnumRepr::I16
852 | EnumRepr::I32
853 | EnumRepr::I64
854 | EnumRepr::USize
855 | EnumRepr::ISize => {
856 }
858 }
859
860 let fr = self.frames.last_mut().unwrap();
862
863 unsafe {
865 match enum_type.enum_repr {
866 EnumRepr::U8 => {
867 let ptr = fr.data.as_mut_byte_ptr();
868 *ptr = discriminant as u8;
869 }
870 EnumRepr::U16 => {
871 let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
872 *ptr = discriminant as u16;
873 }
874 EnumRepr::U32 => {
875 let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
876 *ptr = discriminant as u32;
877 }
878 EnumRepr::U64 => {
879 let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
880 *ptr = discriminant as u64;
881 }
882 EnumRepr::I8 => {
883 let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
884 *ptr = discriminant as i8;
885 }
886 EnumRepr::I16 => {
887 let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
888 *ptr = discriminant as i16;
889 }
890 EnumRepr::I32 => {
891 let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
892 *ptr = discriminant as i32;
893 }
894 EnumRepr::I64 => {
895 let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
896 *ptr = discriminant;
897 }
898 EnumRepr::USize => {
899 let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
900 *ptr = discriminant as usize;
901 }
902 EnumRepr::ISize => {
903 let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
904 *ptr = discriminant as isize;
905 }
906 _ => unreachable!("Already checked enum representation above"),
907 }
908 }
909
910 fr.tracker = Tracker::Enum {
912 variant,
913 data: ISet::new(variant.data.fields.len()),
914 current_child: None,
915 };
916
917 Ok(self)
918 }
919
920 pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
922 self.require_active()?;
923
924 let frame = self.frames.last_mut().unwrap();
925 match frame.shape.ty {
926 Type::Primitive(_) => Err(ReflectError::OperationFailed {
927 shape: frame.shape,
928 operation: "cannot select a field from a primitive type",
929 }),
930 Type::Sequence(_) => Err(ReflectError::OperationFailed {
931 shape: frame.shape,
932 operation: "cannot select a field from a sequence type",
933 }),
934 Type::User(user_type) => match user_type {
935 UserType::Struct(struct_type) => {
936 let idx = struct_type.fields.iter().position(|f| f.name == field_name);
937 let idx = match idx {
938 Some(idx) => idx,
939 None => {
940 return Err(ReflectError::OperationFailed {
941 shape: frame.shape,
942 operation: "field not found",
943 });
944 }
945 };
946 self.begin_nth_field(idx)
947 }
948 UserType::Enum(_) => {
949 match &frame.tracker {
951 Tracker::Enum { variant, .. } => {
952 let idx = variant
953 .data
954 .fields
955 .iter()
956 .position(|f| f.name == field_name);
957 let idx = match idx {
958 Some(idx) => idx,
959 None => {
960 return Err(ReflectError::OperationFailed {
961 shape: frame.shape,
962 operation: "field not found in current enum variant",
963 });
964 }
965 };
966 self.begin_nth_enum_field(idx)
967 }
968 _ => Err(ReflectError::OperationFailed {
969 shape: frame.shape,
970 operation: "must call push_variant before selecting enum fields",
971 }),
972 }
973 }
974 UserType::Union(_) => Err(ReflectError::OperationFailed {
975 shape: frame.shape,
976 operation: "unions are not supported",
977 }),
978 UserType::Opaque => Err(ReflectError::OperationFailed {
979 shape: frame.shape,
980 operation: "opaque types cannot be reflected upon",
981 }),
982 },
983 Type::Pointer(_) => Err(ReflectError::OperationFailed {
984 shape: frame.shape,
985 operation: "cannot select a field from a pointer type",
986 }),
987 }
988 }
989
990 pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
992 self.require_active()?;
993
994 let fr = self.frames.last().unwrap();
995
996 let enum_type = match fr.shape.ty {
998 Type::User(UserType::Enum(e)) => e,
999 _ => {
1000 return Err(ReflectError::OperationFailed {
1001 shape: fr.shape,
1002 operation: "select_nth_variant requires an enum type",
1003 });
1004 }
1005 };
1006
1007 if index >= enum_type.variants.len() {
1008 return Err(ReflectError::OperationFailed {
1009 shape: fr.shape,
1010 operation: "variant index out of bounds",
1011 });
1012 }
1013 let variant = &enum_type.variants[index];
1014
1015 let discriminant = match variant.discriminant {
1017 Some(d) => d,
1018 None => {
1019 return Err(ReflectError::OperationFailed {
1020 shape: fr.shape,
1021 operation: "Variant has no discriminant value",
1022 });
1023 }
1024 };
1025
1026 self.select_variant(discriminant)
1028 }
1029
1030 pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1032 self.require_active()?;
1033 let frame = self.frames.last_mut().unwrap();
1034 match frame.shape.ty {
1035 Type::User(user_type) => match user_type {
1036 UserType::Struct(struct_type) => {
1037 if idx >= struct_type.fields.len() {
1038 return Err(ReflectError::OperationFailed {
1039 shape: frame.shape,
1040 operation: "field index out of bounds",
1041 });
1042 }
1043 let field = &struct_type.fields[idx];
1044 let mut is_field_init = false;
1045
1046 match &mut frame.tracker {
1047 Tracker::Uninit => {
1048 frame.tracker = Tracker::Struct {
1049 iset: ISet::new(struct_type.fields.len()),
1050 current_child: Some(idx),
1051 }
1052 }
1053 Tracker::Struct {
1054 iset,
1055 current_child,
1056 } => {
1057 if iset.get(idx) {
1059 is_field_init = true;
1060 }
1061 *current_child = Some(idx);
1062 }
1063 _ => unreachable!(),
1064 }
1065
1066 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1068 let field_shape = field.shape;
1069 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
1070 if is_field_init {
1071 next_frame.tracker = Tracker::Init;
1072 }
1073 self.frames.push(next_frame);
1074
1075 Ok(self)
1076 }
1077 UserType::Enum(_) => {
1078 match &frame.tracker {
1080 Tracker::Enum { variant, .. } => {
1081 if idx >= variant.data.fields.len() {
1082 return Err(ReflectError::OperationFailed {
1083 shape: frame.shape,
1084 operation: "enum field index out of bounds",
1085 });
1086 }
1087 self.begin_nth_enum_field(idx)
1088 }
1089 _ => Err(ReflectError::OperationFailed {
1090 shape: frame.shape,
1091 operation: "must call select_variant before selecting enum fields",
1092 }),
1093 }
1094 }
1095 UserType::Union(_) => Err(ReflectError::OperationFailed {
1096 shape: frame.shape,
1097 operation: "unions are not supported",
1098 }),
1099 UserType::Opaque => Err(ReflectError::OperationFailed {
1100 shape: frame.shape,
1101 operation: "opaque types cannot be reflected upon",
1102 }),
1103 },
1104 _ => Err(ReflectError::OperationFailed {
1105 shape: frame.shape,
1106 operation: "cannot select a field from this type",
1107 }),
1108 }
1109 }
1110
1111 pub fn begin_nth_element(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1113 self.require_active()?;
1114 let frame = self.frames.last_mut().unwrap();
1115 match frame.shape.ty {
1116 Type::Sequence(seq_type) => match seq_type {
1117 facet_core::SequenceType::Array(array_def) => {
1118 if idx >= array_def.n {
1119 return Err(ReflectError::OperationFailed {
1120 shape: frame.shape,
1121 operation: "array index out of bounds",
1122 });
1123 }
1124
1125 if array_def.n > 63 {
1126 return Err(ReflectError::OperationFailed {
1127 shape: frame.shape,
1128 operation: "arrays larger than 63 elements are not yet supported",
1129 });
1130 }
1131
1132 if matches!(frame.tracker, Tracker::Uninit) {
1134 frame.tracker = Tracker::Array {
1135 iset: ISet::default(),
1136 current_child: None,
1137 };
1138 }
1139
1140 match &mut frame.tracker {
1141 Tracker::Array {
1142 iset,
1143 current_child,
1144 } => {
1145 let element_layout = match array_def.t.layout.sized_layout() {
1147 Ok(layout) => layout,
1148 Err(_) => {
1149 return Err(ReflectError::Unsized {
1150 shape: array_def.t,
1151 operation: "begin_nth_element, calculating array element offset",
1152 });
1153 }
1154 };
1155 let offset = element_layout.size() * idx;
1156
1157 if iset.get(idx) {
1159 let element_ptr = unsafe { frame.data.field_init_at(offset) };
1161 if let Some(drop_fn) =
1162 array_def.t.vtable.sized().and_then(|v| (v.drop_in_place)())
1163 {
1164 unsafe { drop_fn(element_ptr) };
1165 }
1166 iset.unset(idx);
1168 }
1169
1170 *current_child = Some(idx);
1171
1172 let element_data = unsafe { frame.data.field_uninit_at(offset) };
1174 self.frames.push(Frame::new(
1175 element_data,
1176 array_def.t,
1177 FrameOwnership::Field,
1178 ));
1179
1180 Ok(self)
1181 }
1182 _ => Err(ReflectError::OperationFailed {
1183 shape: frame.shape,
1184 operation: "expected array tracker state",
1185 }),
1186 }
1187 }
1188 _ => Err(ReflectError::OperationFailed {
1189 shape: frame.shape,
1190 operation: "can only select elements from arrays",
1191 }),
1192 },
1193 _ => Err(ReflectError::OperationFailed {
1194 shape: frame.shape,
1195 operation: "cannot select an element from this type",
1196 }),
1197 }
1198 }
1199
1200 pub fn begin_nth_enum_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1202 self.require_active()?;
1203 let frame = self.frames.last_mut().unwrap();
1204
1205 let (variant, enum_type) = match (&frame.tracker, &frame.shape.ty) {
1207 (Tracker::Enum { variant, .. }, Type::User(UserType::Enum(e))) => (variant, e),
1208 _ => {
1209 return Err(ReflectError::OperationFailed {
1210 shape: frame.shape,
1211 operation: "push_nth_enum_field requires an enum with a variant selected",
1212 });
1213 }
1214 };
1215
1216 if idx >= variant.data.fields.len() {
1218 return Err(ReflectError::OperationFailed {
1219 shape: frame.shape,
1220 operation: "enum field index out of bounds",
1221 });
1222 }
1223
1224 let field = &variant.data.fields[idx];
1225
1226 match &mut frame.tracker {
1228 Tracker::Enum {
1229 data,
1230 current_child,
1231 ..
1232 } => {
1233 if data.get(idx) {
1235 let _discriminant_size = match enum_type.enum_repr {
1237 EnumRepr::U8 | EnumRepr::I8 => 1,
1238 EnumRepr::U16 | EnumRepr::I16 => 2,
1239 EnumRepr::U32 | EnumRepr::I32 => 4,
1240 EnumRepr::U64 | EnumRepr::I64 => 8,
1241 EnumRepr::USize | EnumRepr::ISize => core::mem::size_of::<usize>(),
1242 EnumRepr::RustNPO => {
1243 return Err(ReflectError::OperationFailed {
1244 shape: frame.shape,
1245 operation: "RustNPO enums are not supported",
1246 });
1247 }
1248 };
1249
1250 let field_ptr = unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
1252
1253 if let Some(drop_fn) =
1254 field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
1255 {
1256 unsafe { drop_fn(PtrMut::new(field_ptr)) };
1257 }
1258
1259 data.unset(idx);
1261 }
1262
1263 *current_child = Some(idx);
1265 }
1266 _ => unreachable!("Already checked that we have Enum tracker"),
1267 }
1268
1269 let field_ptr = unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
1271 let field_shape = field.shape;
1272
1273 self.frames.push(Frame::new(
1275 PtrUninit::new(field_ptr),
1276 field_shape,
1277 FrameOwnership::Field,
1278 ));
1279
1280 Ok(self)
1281 }
1282
1283 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
1285 crate::trace!("begin_smart_ptr()");
1286 self.require_active()?;
1287 let frame = self.frames.last_mut().unwrap();
1288
1289 match &frame.shape.def {
1291 Def::Pointer(smart_ptr_def) => {
1292 match smart_ptr_def.known {
1294 Some(KnownPointer::Box)
1295 | Some(KnownPointer::Rc)
1296 | Some(KnownPointer::Arc)
1297 | Some(KnownPointer::SharedReference) => {
1298 }
1300 _ => {
1301 return Err(ReflectError::OperationFailed {
1302 shape: frame.shape,
1303 operation: "only the following pointers are currently supported: Box<T>, Rc<T>, Arc<T>, and &T",
1304 });
1305 }
1306 }
1307
1308 let pointee_shape = match smart_ptr_def.pointee() {
1310 Some(shape) => shape,
1311 None => {
1312 return Err(ReflectError::OperationFailed {
1313 shape: frame.shape,
1314 operation: "Box must have a pointee shape",
1315 });
1316 }
1317 };
1318
1319 if pointee_shape.layout.sized_layout().is_ok() {
1320 if matches!(frame.tracker, Tracker::Uninit) {
1324 frame.tracker = Tracker::SmartPointer {
1325 is_initialized: false,
1326 };
1327 }
1328
1329 let inner_layout = match pointee_shape.layout.sized_layout() {
1330 Ok(layout) => layout,
1331 Err(_) => {
1332 return Err(ReflectError::Unsized {
1333 shape: pointee_shape,
1334 operation: "begin_smart_ptr, calculating inner value layout",
1335 });
1336 }
1337 };
1338 let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1339 if inner_ptr.is_null() {
1340 return Err(ReflectError::OperationFailed {
1341 shape: frame.shape,
1342 operation: "failed to allocate memory for smart pointer inner value",
1343 });
1344 }
1345
1346 self.frames.push(Frame::new(
1348 PtrUninit::new(inner_ptr),
1349 pointee_shape,
1350 FrameOwnership::Owned,
1351 ));
1352 } else {
1353 if pointee_shape == str::SHAPE {
1355 crate::trace!("Pointee is str");
1356
1357 let string_layout = String::SHAPE
1359 .layout
1360 .sized_layout()
1361 .expect("String must have a sized layout");
1362 let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1363 if string_ptr.is_null() {
1364 alloc::alloc::handle_alloc_error(string_layout);
1365 }
1366 let mut frame = Frame::new(
1367 PtrUninit::new(string_ptr),
1368 String::SHAPE,
1369 FrameOwnership::Owned,
1370 );
1371 frame.tracker = Tracker::SmartPointerStr {
1372 is_initialized: false,
1373 };
1374 self.frames.push(frame);
1375 } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1376 crate::trace!("Pointee is [{}]", _st.t);
1377
1378 let slice_builder_vtable = smart_ptr_def
1380 .vtable
1381 .slice_builder_vtable
1382 .ok_or(ReflectError::OperationFailed {
1383 shape: frame.shape,
1384 operation: "smart pointer does not support slice building",
1385 })?;
1386
1387 let builder_ptr = (slice_builder_vtable.new_fn)();
1389
1390 if let FrameOwnership::Owned = frame.ownership {
1392 if let Ok(layout) = frame.shape.layout.sized_layout() {
1393 if layout.size() > 0 {
1394 unsafe {
1395 alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1396 };
1397 }
1398 }
1399 }
1400
1401 frame.data = PtrUninit::new(builder_ptr.as_mut_byte_ptr());
1403 frame.tracker = Tracker::SmartPointerSlice {
1404 vtable: slice_builder_vtable,
1405 building_item: false,
1406 };
1407 frame.ownership = FrameOwnership::ManagedElsewhere;
1409 } else {
1410 todo!("unsupported unsize pointee shape: {}", pointee_shape)
1411 }
1412 }
1413
1414 Ok(self)
1415 }
1416 _ => Err(ReflectError::OperationFailed {
1417 shape: frame.shape,
1418 operation: "push_smart_ptr can only be called on compatible types",
1419 }),
1420 }
1421 }
1422
1423 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1431 crate::trace!("begin_list()");
1432 self.require_active()?;
1433 let frame = self.frames.last_mut().unwrap();
1434
1435 match &frame.tracker {
1436 Tracker::Uninit => {
1437 }
1439 Tracker::Init => {
1440 frame.tracker = Tracker::List {
1442 is_initialized: true,
1443 current_child: false,
1444 };
1445 return Ok(self);
1446 }
1447 Tracker::List { is_initialized, .. } => {
1448 if *is_initialized {
1449 return Ok(self);
1451 }
1452 }
1453 Tracker::SmartPointerSlice { .. } => {
1454 return Ok(self);
1456 }
1457 _ => {
1458 return Err(ReflectError::UnexpectedTracker {
1459 message: "begin_list called but tracker isn't something list-like",
1460 current_tracker: frame.tracker.kind(),
1461 });
1462 }
1463 };
1464
1465 let list_def = match &frame.shape.def {
1467 Def::List(list_def) => list_def,
1468 _ => {
1469 return Err(ReflectError::OperationFailed {
1470 shape: frame.shape,
1471 operation: "begin_list can only be called on List types",
1472 });
1473 }
1474 };
1475
1476 let init_fn = match list_def.vtable.init_in_place_with_capacity {
1478 Some(f) => f,
1479 None => {
1480 return Err(ReflectError::OperationFailed {
1481 shape: frame.shape,
1482 operation: "list type does not support initialization with capacity",
1483 });
1484 }
1485 };
1486
1487 unsafe {
1489 init_fn(frame.data, 0);
1490 }
1491
1492 frame.tracker = Tracker::List {
1494 is_initialized: true,
1495 current_child: false,
1496 };
1497
1498 Ok(self)
1499 }
1500
1501 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1504 self.require_active()?;
1505 let frame = self.frames.last_mut().unwrap();
1506
1507 let map_def = match &frame.shape.def {
1509 Def::Map(map_def) => map_def,
1510 _ => {
1511 return Err(ReflectError::OperationFailed {
1512 shape: frame.shape,
1513 operation: "begin_map can only be called on Map types",
1514 });
1515 }
1516 };
1517
1518 let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1520
1521 unsafe {
1523 init_fn(frame.data, 0);
1524 }
1525
1526 frame.tracker = Tracker::Map {
1528 is_initialized: true,
1529 insert_state: MapInsertState::Idle,
1530 };
1531
1532 Ok(self)
1533 }
1534
1535 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1538 self.require_active()?;
1539 let frame = self.frames.last_mut().unwrap();
1540
1541 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1543 (
1544 Def::Map(map_def),
1545 Tracker::Map {
1546 is_initialized: true,
1547 insert_state,
1548 },
1549 ) => {
1550 match insert_state {
1551 MapInsertState::Idle => {
1552 *insert_state = MapInsertState::PushingKey { key_ptr: None };
1554 }
1555 MapInsertState::PushingKey { key_ptr } => {
1556 if key_ptr.is_some() {
1557 return Err(ReflectError::OperationFailed {
1558 shape: frame.shape,
1559 operation: "already pushing a key, call end() first",
1560 });
1561 }
1562 }
1563 _ => {
1564 return Err(ReflectError::OperationFailed {
1565 shape: frame.shape,
1566 operation: "must complete current operation before begin_key()",
1567 });
1568 }
1569 }
1570 map_def
1571 }
1572 _ => {
1573 return Err(ReflectError::OperationFailed {
1574 shape: frame.shape,
1575 operation: "must call begin_map() before begin_key()",
1576 });
1577 }
1578 };
1579
1580 let key_shape = map_def.k();
1582
1583 let key_layout = match key_shape.layout.sized_layout() {
1585 Ok(layout) => layout,
1586 Err(_) => {
1587 return Err(ReflectError::Unsized {
1588 shape: key_shape,
1589 operation: "begin_key allocating key",
1590 });
1591 }
1592 };
1593 let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1594
1595 if key_ptr_raw.is_null() {
1596 return Err(ReflectError::OperationFailed {
1597 shape: frame.shape,
1598 operation: "failed to allocate memory for map key",
1599 });
1600 }
1601
1602 match &mut frame.tracker {
1604 Tracker::Map {
1605 insert_state: MapInsertState::PushingKey { key_ptr: kp },
1606 ..
1607 } => {
1608 *kp = Some(PtrUninit::new(key_ptr_raw));
1609 }
1610 _ => unreachable!(),
1611 }
1612
1613 self.frames.push(Frame::new(
1615 PtrUninit::new(key_ptr_raw),
1616 key_shape,
1617 FrameOwnership::ManagedElsewhere, ));
1619
1620 Ok(self)
1621 }
1622
1623 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1626 self.require_active()?;
1627 let frame = self.frames.last_mut().unwrap();
1628
1629 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1631 (
1632 Def::Map(map_def),
1633 Tracker::Map {
1634 insert_state: MapInsertState::PushingValue { value_ptr, .. },
1635 ..
1636 },
1637 ) => {
1638 if value_ptr.is_some() {
1639 return Err(ReflectError::OperationFailed {
1640 shape: frame.shape,
1641 operation: "already pushing a value, call pop() first",
1642 });
1643 }
1644 map_def
1645 }
1646 _ => {
1647 return Err(ReflectError::OperationFailed {
1648 shape: frame.shape,
1649 operation: "must complete key before push_value()",
1650 });
1651 }
1652 };
1653
1654 let value_shape = map_def.v();
1656
1657 let value_layout = match value_shape.layout.sized_layout() {
1659 Ok(layout) => layout,
1660 Err(_) => {
1661 return Err(ReflectError::Unsized {
1662 shape: value_shape,
1663 operation: "begin_value allocating value",
1664 });
1665 }
1666 };
1667 let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1668
1669 if value_ptr_raw.is_null() {
1670 return Err(ReflectError::OperationFailed {
1671 shape: frame.shape,
1672 operation: "failed to allocate memory for map value",
1673 });
1674 }
1675
1676 match &mut frame.tracker {
1678 Tracker::Map {
1679 insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1680 ..
1681 } => {
1682 *vp = Some(PtrUninit::new(value_ptr_raw));
1683 }
1684 _ => unreachable!(),
1685 }
1686
1687 self.frames.push(Frame::new(
1689 PtrUninit::new(value_ptr_raw),
1690 value_shape,
1691 FrameOwnership::ManagedElsewhere, ));
1693
1694 Ok(self)
1695 }
1696
1697 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1700 crate::trace!("begin_list_item()");
1701 self.require_active()?;
1702 let frame = self.frames.last_mut().unwrap();
1703
1704 if let Tracker::SmartPointerSlice {
1706 building_item,
1707 vtable: _,
1708 } = &frame.tracker
1709 {
1710 if *building_item {
1711 return Err(ReflectError::OperationFailed {
1712 shape: frame.shape,
1713 operation: "already building an item, call end() first",
1714 });
1715 }
1716
1717 let element_shape = match &frame.shape.def {
1719 Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1720 Some(pointee_shape) => match &pointee_shape.ty {
1721 Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1722 _ => {
1723 return Err(ReflectError::OperationFailed {
1724 shape: frame.shape,
1725 operation: "smart pointer pointee is not a slice",
1726 });
1727 }
1728 },
1729 None => {
1730 return Err(ReflectError::OperationFailed {
1731 shape: frame.shape,
1732 operation: "smart pointer has no pointee",
1733 });
1734 }
1735 },
1736 _ => {
1737 return Err(ReflectError::OperationFailed {
1738 shape: frame.shape,
1739 operation: "expected smart pointer definition",
1740 });
1741 }
1742 };
1743
1744 crate::trace!("Pointee is a slice of {element_shape}");
1746 let element_layout = match element_shape.layout.sized_layout() {
1747 Ok(layout) => layout,
1748 Err(_) => {
1749 return Err(ReflectError::OperationFailed {
1750 shape: element_shape,
1751 operation: "cannot allocate unsized element",
1752 });
1753 }
1754 };
1755
1756 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1757 if element_ptr.is_null() {
1758 alloc::alloc::handle_alloc_error(element_layout);
1759 }
1760
1761 crate::trace!("Pushing element frame, which we just allocated");
1763 let element_frame = Frame::new(
1764 PtrUninit::new(element_ptr),
1765 element_shape,
1766 FrameOwnership::Owned,
1767 );
1768 self.frames.push(element_frame);
1769
1770 let parent_idx = self.frames.len() - 2;
1773 if let Tracker::SmartPointerSlice { building_item, .. } =
1774 &mut self.frames[parent_idx].tracker
1775 {
1776 crate::trace!("Marking element frame as building item");
1777 *building_item = true;
1778 }
1779
1780 return Ok(self);
1781 }
1782
1783 let list_def = match &frame.shape.def {
1785 Def::List(list_def) => list_def,
1786 _ => {
1787 return Err(ReflectError::OperationFailed {
1788 shape: frame.shape,
1789 operation: "push can only be called on List types",
1790 });
1791 }
1792 };
1793
1794 match &mut frame.tracker {
1796 Tracker::List {
1797 is_initialized: true,
1798 current_child,
1799 } => {
1800 if *current_child {
1801 return Err(ReflectError::OperationFailed {
1802 shape: frame.shape,
1803 operation: "already pushing an element, call pop() first",
1804 });
1805 }
1806 *current_child = true;
1807 }
1808 _ => {
1809 return Err(ReflectError::OperationFailed {
1810 shape: frame.shape,
1811 operation: "must call begin_list() before push()",
1812 });
1813 }
1814 }
1815
1816 let element_shape = list_def.t();
1818
1819 let element_layout = match element_shape.layout.sized_layout() {
1821 Ok(layout) => layout,
1822 Err(_) => {
1823 return Err(ReflectError::Unsized {
1824 shape: element_shape,
1825 operation: "begin_list_item: calculating element layout",
1826 });
1827 }
1828 };
1829 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1830
1831 if element_ptr.is_null() {
1832 return Err(ReflectError::OperationFailed {
1833 shape: frame.shape,
1834 operation: "failed to allocate memory for list element",
1835 });
1836 }
1837
1838 self.frames.push(Frame::new(
1840 PtrUninit::new(element_ptr),
1841 element_shape,
1842 FrameOwnership::Owned,
1843 ));
1844
1845 Ok(self)
1846 }
1847
1848 pub fn end(&mut self) -> Result<&mut Self, ReflectError> {
1850 crate::trace!("end() called");
1851 self.require_active()?;
1852
1853 if self.frames.len() == 1 {
1855 if let Tracker::SmartPointerSlice {
1856 vtable,
1857 building_item,
1858 } = &self.frames[0].tracker
1859 {
1860 if *building_item {
1861 return Err(ReflectError::OperationFailed {
1862 shape: self.frames[0].shape,
1863 operation: "still building an item, finish it first",
1864 });
1865 }
1866
1867 let builder_ptr = unsafe { self.frames[0].data.assume_init() };
1869 let arc_ptr = unsafe { (vtable.convert_fn)(builder_ptr) };
1870
1871 self.frames[0].data = PtrUninit::new(arc_ptr.as_byte_ptr() as *mut u8);
1873 self.frames[0].tracker = Tracker::Init;
1874 self.frames[0].ownership = FrameOwnership::ManagedElsewhere;
1876
1877 return Ok(self);
1878 }
1879 }
1880
1881 if self.frames.len() <= 1 {
1882 return Err(ReflectError::InvariantViolation {
1884 invariant: "Partial::end() called with only one frame on the stack",
1885 });
1886 }
1887
1888 {
1890 let frame = self.frames.last().unwrap();
1891 trace!(
1892 "end(): Checking full initialization for frame with shape {} and tracker {:?}",
1893 frame.shape,
1894 frame.tracker.kind()
1895 );
1896 frame.require_full_initialization()?
1897 }
1898
1899 let popped_frame = self.frames.pop().unwrap();
1901
1902 let parent_frame = self.frames.last_mut().unwrap();
1904
1905 trace!(
1906 "end(): Popped {} (tracker {:?}), Parent {} (tracker {:?})",
1907 popped_frame.shape,
1908 popped_frame.tracker.kind(),
1909 parent_frame.shape,
1910 parent_frame.tracker.kind()
1911 );
1912
1913 let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
1918 && parent_frame.shape.inner.is_some()
1919 && parent_frame.shape.inner.unwrap()() == popped_frame.shape
1920 && parent_frame
1921 .shape
1922 .vtable
1923 .sized()
1924 .and_then(|v| (v.try_from)())
1925 .is_some();
1926
1927 if needs_conversion {
1928 trace!(
1929 "Detected implicit conversion needed from {} to {}",
1930 popped_frame.shape, parent_frame.shape
1931 );
1932 if let Some(try_from_fn) = parent_frame
1934 .shape
1935 .vtable
1936 .sized()
1937 .and_then(|v| (v.try_from)())
1938 {
1939 let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
1940 let inner_shape = popped_frame.shape;
1941
1942 trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
1943 let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
1944
1945 if let Err(e) = result {
1946 trace!("Conversion failed: {e:?}");
1947
1948 if let FrameOwnership::Owned = popped_frame.ownership {
1950 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1951 if layout.size() > 0 {
1952 trace!(
1953 "Deallocating conversion frame memory after failure: size={}, align={}",
1954 layout.size(),
1955 layout.align()
1956 );
1957 unsafe {
1958 alloc::alloc::dealloc(
1959 popped_frame.data.as_mut_byte_ptr(),
1960 layout,
1961 );
1962 }
1963 }
1964 }
1965 }
1966
1967 return Err(ReflectError::TryFromError {
1968 src_shape: inner_shape,
1969 dst_shape: parent_frame.shape,
1970 inner: e,
1971 });
1972 }
1973
1974 trace!("Conversion succeeded, marking parent as initialized");
1975 parent_frame.tracker = Tracker::Init;
1976
1977 if let FrameOwnership::Owned = popped_frame.ownership {
1979 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1980 if layout.size() > 0 {
1981 trace!(
1982 "Deallocating conversion frame memory: size={}, align={}",
1983 layout.size(),
1984 layout.align()
1985 );
1986 unsafe {
1987 alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
1988 }
1989 }
1990 }
1991 }
1992
1993 return Ok(self);
1994 }
1995 }
1996
1997 match &mut parent_frame.tracker {
1998 Tracker::Struct {
1999 iset,
2000 current_child,
2001 } => {
2002 if let Some(idx) = *current_child {
2003 iset.set(idx);
2004 *current_child = None;
2005 }
2006 }
2007 Tracker::Array {
2008 iset,
2009 current_child,
2010 } => {
2011 if let Some(idx) = *current_child {
2012 iset.set(idx);
2013 *current_child = None;
2014 }
2015 }
2016 Tracker::SmartPointer { is_initialized } => {
2017 if let Def::Pointer(smart_ptr_def) = parent_frame.shape.def {
2019 if let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn {
2020 let inner_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
2022
2023 unsafe {
2025 new_into_fn(parent_frame.data, inner_ptr);
2026 }
2027
2028 if let FrameOwnership::Owned = popped_frame.ownership {
2030 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2031 if layout.size() > 0 {
2032 unsafe {
2033 alloc::alloc::dealloc(
2034 popped_frame.data.as_mut_byte_ptr(),
2035 layout,
2036 );
2037 }
2038 }
2039 }
2040 }
2041
2042 *is_initialized = true;
2043 } else {
2044 return Err(ReflectError::OperationFailed {
2045 shape: parent_frame.shape,
2046 operation: "SmartPointer missing new_into_fn",
2047 });
2048 }
2049 }
2050 }
2051 Tracker::Enum {
2052 data,
2053 current_child,
2054 ..
2055 } => {
2056 if let Some(idx) = *current_child {
2057 data.set(idx);
2058 *current_child = None;
2059 }
2060 }
2061 Tracker::List {
2062 is_initialized: true,
2063 current_child,
2064 } => {
2065 if *current_child {
2066 if let Def::List(list_def) = parent_frame.shape.def {
2068 if let Some(push_fn) = list_def.vtable.push {
2069 let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
2071
2072 unsafe {
2074 push_fn(
2075 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
2076 element_ptr,
2077 );
2078 }
2079
2080 if let FrameOwnership::Owned = popped_frame.ownership {
2082 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2083 if layout.size() > 0 {
2084 unsafe {
2085 alloc::alloc::dealloc(
2086 popped_frame.data.as_mut_byte_ptr(),
2087 layout,
2088 );
2089 }
2090 }
2091 }
2092 }
2093
2094 *current_child = false;
2095 } else {
2096 return Err(ReflectError::OperationFailed {
2097 shape: parent_frame.shape,
2098 operation: "List missing push function",
2099 });
2100 }
2101 }
2102 }
2103 }
2104 Tracker::Map {
2105 is_initialized: true,
2106 insert_state,
2107 } => {
2108 match insert_state {
2109 MapInsertState::PushingKey { key_ptr } => {
2110 if let Some(key_ptr) = key_ptr {
2112 *insert_state = MapInsertState::PushingValue {
2114 key_ptr: *key_ptr,
2115 value_ptr: None,
2116 };
2117 }
2118 }
2119 MapInsertState::PushingValue { key_ptr, value_ptr } => {
2120 if let (Some(value_ptr), Def::Map(map_def)) =
2122 (value_ptr, parent_frame.shape.def)
2123 {
2124 let insert_fn = map_def.vtable.insert_fn;
2125
2126 unsafe {
2128 insert_fn(
2129 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
2130 PtrMut::new(key_ptr.as_mut_byte_ptr()),
2131 PtrMut::new(value_ptr.as_mut_byte_ptr()),
2132 );
2133 }
2134
2135 if let Ok(key_shape) = map_def.k().layout.sized_layout() {
2141 if key_shape.size() > 0 {
2142 unsafe {
2143 alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
2144 }
2145 }
2146 }
2147 if let Ok(value_shape) = map_def.v().layout.sized_layout() {
2148 if value_shape.size() > 0 {
2149 unsafe {
2150 alloc::alloc::dealloc(
2151 value_ptr.as_mut_byte_ptr(),
2152 value_shape,
2153 );
2154 }
2155 }
2156 }
2157
2158 *insert_state = MapInsertState::Idle;
2160 }
2161 }
2162 MapInsertState::Idle => {
2163 }
2165 }
2166 }
2167 Tracker::Option { building_inner } => {
2168 if *building_inner {
2170 if let Def::Option(option_def) = parent_frame.shape.def {
2171 let init_some_fn = option_def.vtable.init_some_fn;
2173
2174 let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
2176
2177 unsafe {
2179 init_some_fn(parent_frame.data, inner_value_ptr);
2180 }
2181
2182 if let FrameOwnership::Owned = popped_frame.ownership {
2184 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2185 if layout.size() > 0 {
2186 unsafe {
2187 alloc::alloc::dealloc(
2188 popped_frame.data.as_mut_byte_ptr(),
2189 layout,
2190 );
2191 }
2192 }
2193 }
2194 }
2195
2196 *building_inner = false;
2198 } else {
2199 return Err(ReflectError::OperationFailed {
2200 shape: parent_frame.shape,
2201 operation: "Option frame without Option definition",
2202 });
2203 }
2204 }
2205 }
2206 Tracker::Uninit | Tracker::Init => {
2207 match popped_frame.tracker {
2208 Tracker::SmartPointerStr { is_initialized } => {
2209 if !is_initialized {
2210 return Err(ReflectError::InvariantViolation {
2211 invariant: "popping smart pointer str without initializing it",
2212 });
2213 }
2214
2215 use alloc::{rc::Rc, string::String, sync::Arc};
2220 let parent_shape = parent_frame.shape;
2221
2222 if let Def::Pointer(smart_ptr_def) = parent_shape.def {
2223 if let Some(known) = smart_ptr_def.known {
2224 if matches!(parent_frame.tracker, Tracker::Init) {
2227 if let Some(drop_fn) = parent_frame
2228 .shape
2229 .vtable
2230 .sized()
2231 .and_then(|v| (v.drop_in_place)())
2232 {
2233 unsafe { drop_fn(parent_frame.data.assume_init()) };
2234 }
2235 parent_frame.tracker = Tracker::Uninit;
2236 }
2237
2238 let string_ptr = popped_frame.data.as_mut_byte_ptr() as *mut String;
2241 let string_value = unsafe { core::ptr::read(string_ptr) };
2242
2243 match known {
2244 KnownPointer::Box => {
2245 let boxed: Box<str> = string_value.into_boxed_str();
2246 unsafe {
2247 core::ptr::write(
2248 parent_frame.data.as_mut_byte_ptr()
2249 as *mut Box<str>,
2250 boxed,
2251 );
2252 }
2253 }
2254 KnownPointer::Arc => {
2255 let arc: Arc<str> =
2256 Arc::from(string_value.into_boxed_str());
2257 unsafe {
2258 core::ptr::write(
2259 parent_frame.data.as_mut_byte_ptr()
2260 as *mut Arc<str>,
2261 arc,
2262 );
2263 }
2264 }
2265 KnownPointer::Rc => {
2266 let rc: Rc<str> = Rc::from(string_value.into_boxed_str());
2267 unsafe {
2268 core::ptr::write(
2269 parent_frame.data.as_mut_byte_ptr() as *mut Rc<str>,
2270 rc,
2271 );
2272 }
2273 }
2274 _ => {}
2275 }
2276 parent_frame.tracker = Tracker::Init;
2277
2278 if let FrameOwnership::Owned = popped_frame.ownership {
2280 if let Ok(layout) = String::SHAPE.layout.sized_layout() {
2281 if layout.size() > 0 {
2282 unsafe {
2283 alloc::alloc::dealloc(
2284 popped_frame.data.as_mut_byte_ptr(),
2285 layout,
2286 )
2287 };
2288 }
2289 }
2290 }
2291 } else {
2292 return Err(ReflectError::OperationFailed {
2293 shape: parent_shape,
2294 operation: "SmartPointerStr for unknown smart pointer kind",
2295 });
2296 }
2297 }
2298 }
2299 _ => {
2300 return Err(ReflectError::OperationFailed {
2301 shape: parent_frame.shape,
2302 operation: "end()-ing a frame but the parent is Init/Uninit, that's... confusing?",
2303 });
2304 }
2305 }
2306 }
2307 Tracker::SmartPointerSlice {
2308 vtable,
2309 building_item,
2310 } => {
2311 if *building_item {
2312 let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
2314
2315 crate::trace!("Pushing element to slice builder");
2317 unsafe {
2318 let parent_ptr = parent_frame.data.assume_init();
2319 (vtable.push_fn)(parent_ptr, element_ptr);
2320 }
2321
2322 if let FrameOwnership::Owned = popped_frame.ownership {
2324 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2325 if layout.size() > 0 {
2326 unsafe {
2327 alloc::alloc::dealloc(
2328 popped_frame.data.as_mut_byte_ptr(),
2329 layout,
2330 );
2331 }
2332 }
2333 }
2334 }
2335
2336 if let Tracker::SmartPointerSlice {
2337 building_item: bi, ..
2338 } = &mut parent_frame.tracker
2339 {
2340 *bi = false;
2341 }
2342 }
2343 }
2344 _ => {}
2345 }
2346
2347 Ok(self)
2348 }
2349
2350 pub fn build(&mut self) -> Result<HeapValue<'facet>, ReflectError> {
2352 self.require_active()?;
2353 if self.frames.len() != 1 {
2354 self.state = PartialState::BuildFailed;
2355 return Err(ReflectError::InvariantViolation {
2356 invariant: "Partial::build() expects a single frame — call end() until that's the case",
2357 });
2358 }
2359
2360 let frame = self.frames.pop().unwrap();
2361
2362 if let Err(e) = frame.require_full_initialization() {
2364 self.frames.push(frame);
2366 self.state = PartialState::BuildFailed;
2367 return Err(e);
2368 }
2369
2370 if let Some(invariants_fn) = frame.shape.vtable.sized().and_then(|v| (v.invariants)()) {
2372 let value_ptr = unsafe { frame.data.assume_init().as_const() };
2374 let invariants_ok = unsafe { invariants_fn(value_ptr) };
2375
2376 if !invariants_ok {
2377 self.frames.push(frame);
2379 self.state = PartialState::BuildFailed;
2380 return Err(ReflectError::InvariantViolation {
2381 invariant: "Type invariants check failed",
2382 });
2383 }
2384 }
2385
2386 self.state = PartialState::Built;
2388
2389 match frame
2390 .shape
2391 .layout
2392 .sized_layout()
2393 .map_err(|_layout_err| ReflectError::Unsized {
2394 shape: frame.shape,
2395 operation: "build (final check for sized layout)",
2396 }) {
2397 Ok(layout) => Ok(HeapValue {
2398 guard: Some(Guard {
2399 ptr: frame.data.as_mut_byte_ptr(),
2400 layout,
2401 }),
2402 shape: frame.shape,
2403 phantom: PhantomData,
2404 }),
2405 Err(e) => {
2406 self.frames.push(frame);
2408 self.state = PartialState::BuildFailed;
2409 Err(e)
2410 }
2411 }
2412 }
2413
2414 pub fn path(&self) -> String {
2417 let mut out = String::new();
2418
2419 let mut path_components = Vec::new();
2420 for (i, frame) in self.frames.iter().enumerate() {
2423 match frame.shape.ty {
2424 Type::User(user_type) => match user_type {
2425 UserType::Struct(struct_type) => {
2426 let mut field_str = None;
2428 if let Tracker::Struct {
2429 current_child: Some(idx),
2430 ..
2431 } = &frame.tracker
2432 {
2433 if let Some(field) = struct_type.fields.get(*idx) {
2434 field_str = Some(field.name);
2435 }
2436 }
2437 if i == 0 {
2438 path_components.push(format!("{}", frame.shape));
2440 }
2441 if let Some(field_name) = field_str {
2442 path_components.push(format!(".{field_name}"));
2443 }
2444 }
2445 UserType::Enum(_enum_type) => {
2446 if let Tracker::Enum {
2448 variant,
2449 current_child,
2450 ..
2451 } = &frame.tracker
2452 {
2453 if i == 0 {
2454 path_components.push(format!("{}", frame.shape));
2456 }
2457 path_components.push(format!("::{}", variant.name));
2458 if let Some(idx) = *current_child {
2459 if let Some(field) = variant.data.fields.get(idx) {
2460 path_components.push(format!(".{}", field.name));
2461 }
2462 }
2463 } else if i == 0 {
2464 path_components.push(format!("{}", frame.shape));
2466 }
2467 }
2468 UserType::Union(_union_type) => {
2469 path_components.push(format!("{}", frame.shape));
2470 }
2471 UserType::Opaque => {
2472 path_components.push("<opaque>".to_string());
2473 }
2474 },
2475 Type::Sequence(seq_type) => match seq_type {
2476 facet_core::SequenceType::Array(_array_def) => {
2477 if let Tracker::Array {
2479 current_child: Some(idx),
2480 ..
2481 } = &frame.tracker
2482 {
2483 path_components.push(format!("[{idx}]"));
2484 }
2485 }
2486 _ => {
2488 path_components.push("[]".to_string());
2490 }
2491 },
2492 Type::Pointer(_) => {
2493 path_components.push("*".to_string());
2495 }
2496 _ => {
2497 }
2499 }
2500 }
2501 for component in path_components {
2503 out.push_str(&component);
2504 }
2505 out
2506 }
2507
2508 #[inline]
2510 pub fn shape(&self) -> &'static Shape {
2511 self.frames
2512 .last()
2513 .expect("Partial always has at least one frame")
2514 .shape
2515 }
2516
2517 #[inline]
2519 pub fn innermost_shape(&self) -> &'static Shape {
2520 self.shape()
2521 }
2522
2523 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
2525 let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
2526
2527 match &frame.tracker {
2528 Tracker::Uninit => Ok(false),
2529 Tracker::Init => Ok(true),
2530 Tracker::Struct { iset, .. } => Ok(iset.get(index)),
2531 Tracker::Enum { data, .. } => {
2532 if data.get(index) {
2534 return Ok(true);
2535 }
2536
2537 if let Tracker::Enum { variant, .. } = &frame.tracker {
2539 if let Some(field) = variant.data.fields.get(index) {
2540 if let Type::User(UserType::Struct(field_struct)) = field.shape.ty {
2541 if field_struct.fields.is_empty() {
2542 return Ok(true);
2543 }
2544 }
2545 }
2546 }
2547
2548 Ok(false)
2549 }
2550 Tracker::Option { building_inner } => {
2551 if index == 0 {
2553 Ok(!building_inner)
2554 } else {
2555 Err(ReflectError::InvalidOperation {
2556 operation: "is_field_set",
2557 reason: "Option only has one field (index 0)",
2558 })
2559 }
2560 }
2561 _ => Err(ReflectError::InvalidOperation {
2562 operation: "is_field_set",
2563 reason: "Current frame is not a struct, enum variant, or option",
2564 }),
2565 }
2566 }
2567
2568 pub fn field_index(&self, field_name: &str) -> Option<usize> {
2570 let frame = self.frames.last()?;
2571
2572 match frame.shape.ty {
2573 Type::User(UserType::Struct(struct_def)) => {
2574 struct_def.fields.iter().position(|f| f.name == field_name)
2575 }
2576 Type::User(UserType::Enum(_)) => {
2577 if let Tracker::Enum { variant, .. } = &frame.tracker {
2579 variant
2580 .data
2581 .fields
2582 .iter()
2583 .position(|f| f.name == field_name)
2584 } else {
2585 None
2586 }
2587 }
2588 _ => None,
2589 }
2590 }
2591
2592 pub fn selected_variant(&self) -> Option<Variant> {
2594 let frame = self.frames.last()?;
2595
2596 match &frame.tracker {
2597 Tracker::Enum { variant, .. } => Some(**variant),
2598 _ => None,
2599 }
2600 }
2601
2602 pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'static Variant)> {
2604 let frame = self.frames.last()?;
2605
2606 if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
2607 enum_def
2608 .variants
2609 .iter()
2610 .enumerate()
2611 .find(|(_, v)| v.name == variant_name)
2612 } else {
2613 None
2614 }
2615 }
2616
2617 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
2619 self.require_active()?;
2620 let frame = self.frames.last_mut().unwrap();
2621
2622 let option_def = match frame.shape.def {
2624 Def::Option(def) => def,
2625 _ => {
2626 return Err(ReflectError::WasNotA {
2627 expected: "Option",
2628 actual: frame.shape,
2629 });
2630 }
2631 };
2632
2633 if matches!(frame.tracker, Tracker::Uninit) {
2635 frame.tracker = Tracker::Option {
2636 building_inner: true,
2637 };
2638 }
2639
2640 let inner_shape = option_def.t;
2642
2643 let inner_layout =
2645 inner_shape
2646 .layout
2647 .sized_layout()
2648 .map_err(|_| ReflectError::Unsized {
2649 shape: inner_shape,
2650 operation: "begin_some, allocating Option inner value",
2651 })?;
2652
2653 let inner_data = if inner_layout.size() == 0 {
2654 PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2656 } else {
2657 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2659 if ptr.is_null() {
2660 alloc::alloc::handle_alloc_error(inner_layout);
2661 }
2662 PtrUninit::new(ptr)
2663 };
2664
2665 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
2667 self.frames.push(inner_frame);
2668
2669 Ok(self)
2670 }
2671
2672 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
2674 self.require_active()?;
2675
2676 let (inner_shape, has_try_from, parent_shape) = {
2678 let frame = self.frames.last().unwrap();
2679 if let Some(inner_fn) = frame.shape.inner {
2680 let inner_shape = inner_fn();
2681 let has_try_from = frame
2682 .shape
2683 .vtable
2684 .sized()
2685 .and_then(|v| (v.try_from)())
2686 .is_some();
2687 (Some(inner_shape), has_try_from, frame.shape)
2688 } else {
2689 (None, false, frame.shape)
2690 }
2691 };
2692
2693 if let Some(inner_shape) = inner_shape {
2694 if has_try_from {
2695 let inner_layout =
2702 inner_shape
2703 .layout
2704 .sized_layout()
2705 .map_err(|_| ReflectError::Unsized {
2706 shape: inner_shape,
2707 operation: "begin_inner, getting inner layout",
2708 })?;
2709
2710 let inner_data = if inner_layout.size() == 0 {
2711 PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2713 } else {
2714 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2716 if ptr.is_null() {
2717 alloc::alloc::handle_alloc_error(inner_layout);
2718 }
2719 PtrUninit::new(ptr)
2720 };
2721
2722 trace!(
2726 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
2727 );
2728 self.frames
2729 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2730
2731 Ok(self)
2732 } else {
2733 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
2736 self.begin_nth_field(0)
2737 }
2738 } else {
2739 Err(ReflectError::OperationFailed {
2740 shape: parent_shape,
2741 operation: "type does not have an inner value",
2742 })
2743 }
2744 }
2745
2746 pub fn set_from_peek(&mut self, peek: &Peek<'_, '_>) -> Result<&mut Self, ReflectError> {
2748 self.require_active()?;
2749
2750 let src_ptr = peek.data();
2752 let src_shape = peek.shape();
2753
2754 unsafe { self.set_shape(src_ptr.thin().unwrap(), src_shape) }
2757 }
2758
2759 pub fn set_field_from_default(
2762 &mut self,
2763 field_data: PtrConst<'_>,
2764 field_shape: &'static Shape,
2765 ) -> Result<&mut Self, ReflectError> {
2766 self.require_active()?;
2767
2768 unsafe { self.set_shape(field_data, field_shape) }
2771 }
2772
2773 pub fn fill_unset_fields_from_default(&mut self) -> Result<&mut Self, ReflectError> {
2776 self.require_active()?;
2777
2778 let frame = self.frames.last().unwrap();
2779 let shape = frame.shape;
2780
2781 if !shape.has_default_attr() {
2783 return Ok(self);
2784 }
2785
2786 let struct_def = match shape.ty {
2788 Type::User(UserType::Struct(sd)) => sd,
2789 _ => return Ok(self), };
2791
2792 let mut has_unset = false;
2794 for index in 0..struct_def.fields.len() {
2795 if !self.is_field_set(index)? {
2796 has_unset = true;
2797 break;
2798 }
2799 }
2800
2801 if !has_unset {
2802 return Ok(self); }
2804
2805 let default_val = Partial::alloc_shape(shape)?.set_default()?.build()?;
2807 let peek = default_val.peek();
2808
2809 let struct_peek = peek
2811 .into_struct()
2812 .map_err(|_| ReflectError::OperationFailed {
2813 shape,
2814 operation: "expected struct peek for default value",
2815 })?;
2816
2817 for (index, _field) in struct_def.fields.iter().enumerate() {
2819 if !self.is_field_set(index)? {
2820 self.begin_nth_field(index)?;
2821
2822 let def_field =
2824 struct_peek
2825 .field(index)
2826 .map_err(|_| ReflectError::OperationFailed {
2827 shape,
2828 operation: "failed to get field from default struct",
2829 })?;
2830
2831 self.set_from_peek(&def_field)?;
2832 self.end()?;
2833 }
2834 }
2835
2836 Ok(self)
2837 }
2838
2839 pub fn set_nth_element<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2841 where
2842 U: Facet<'facet>,
2843 {
2844 self.begin_nth_element(idx)?.set(value)?.end()
2845 }
2846
2847 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2849 where
2850 U: Facet<'facet>,
2851 {
2852 self.begin_nth_field(idx)?.set(value)?.end()
2853 }
2854
2855 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
2857 where
2858 U: Facet<'facet>,
2859 {
2860 self.begin_field(field_name)?.set(value)?.end()
2861 }
2862
2863 pub fn set_nth_enum_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2865 where
2866 U: Facet<'facet>,
2867 {
2868 self.begin_nth_enum_field(idx)?.set(value)?.end()
2869 }
2870
2871 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2873 where
2874 U: Facet<'facet>,
2875 {
2876 self.begin_key()?.set(value)?.end()
2877 }
2878
2879 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2881 where
2882 U: Facet<'facet>,
2883 {
2884 self.begin_value()?.set(value)?.end()
2885 }
2886
2887 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2889 where
2890 U: Facet<'facet>,
2891 {
2892 self.begin_list_item()?.set(value)?.end()
2893 }
2894}
2895
2896pub struct TypedPartial<'facet, T> {
2899 inner: Partial<'facet>,
2900 phantom: PhantomData<T>,
2901}
2902
2903impl<'facet, T> TypedPartial<'facet, T> {
2904 pub fn inner_mut(&mut self) -> &mut Partial<'facet> {
2906 &mut self.inner
2907 }
2908
2909 pub fn build(&mut self) -> Result<Box<T>, ReflectError>
2911 where
2912 T: Facet<'facet>,
2913 {
2914 trace!(
2915 "TypedPartial::build: Building value for type {} which should == {}",
2916 T::SHAPE,
2917 self.inner.shape()
2918 );
2919 let heap_value = self.inner.build()?;
2920 trace!(
2921 "TypedPartial::build: Built heap value with shape: {}",
2922 heap_value.shape()
2923 );
2924 let result = unsafe { heap_value.into_box_unchecked::<T>() };
2926 trace!("TypedPartial::build: Successfully converted to Box<T>");
2927 Ok(result)
2928 }
2929
2930 pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2932 where
2933 U: Facet<'facet>,
2934 {
2935 self.inner.set(value)?;
2936 Ok(self)
2937 }
2938
2939 pub fn set_shape(
2941 &mut self,
2942 src_value: PtrConst<'_>,
2943 src_shape: &'static Shape,
2944 ) -> Result<&mut Self, ReflectError> {
2945 unsafe { self.inner.set_shape(src_value, src_shape)? };
2946 Ok(self)
2947 }
2948
2949 pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
2951 self.inner.begin_field(field_name)?;
2952 Ok(self)
2953 }
2954
2955 pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
2957 self.inner.begin_nth_field(idx)?;
2958 Ok(self)
2959 }
2960
2961 pub fn begin_nth_element(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
2963 self.inner.begin_nth_element(idx)?;
2964 Ok(self)
2965 }
2966
2967 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
2969 self.inner.begin_smart_ptr()?;
2970 Ok(self)
2971 }
2972
2973 pub fn end(&mut self) -> Result<&mut Self, ReflectError> {
2975 self.inner.end()?;
2976 Ok(self)
2977 }
2978
2979 pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
2981 self.inner.set_default()?;
2982 Ok(self)
2983 }
2984
2985 pub fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
2987 where
2988 F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
2989 {
2990 self.inner.set_from_function(f)?;
2991 Ok(self)
2992 }
2993
2994 pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
2996 self.inner.parse_from_str(s)?;
2997 Ok(self)
2998 }
2999
3000 pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
3002 self.inner.select_variant(discriminant)?;
3003 Ok(self)
3004 }
3005
3006 pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
3008 self.inner.select_variant_named(variant_name)?;
3009 Ok(self)
3010 }
3011
3012 pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
3014 self.inner.select_nth_variant(index)?;
3015 Ok(self)
3016 }
3017
3018 pub fn begin_nth_enum_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
3020 self.inner.begin_nth_enum_field(idx)?;
3021 Ok(self)
3022 }
3023
3024 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
3026 self.inner.begin_list()?;
3027 Ok(self)
3028 }
3029
3030 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
3032 self.inner.begin_list_item()?;
3033 Ok(self)
3034 }
3035
3036 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
3038 self.inner.begin_map()?;
3039 Ok(self)
3040 }
3041
3042 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
3044 self.inner.begin_key()?;
3045 Ok(self)
3046 }
3047
3048 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
3050 self.inner.begin_value()?;
3051 Ok(self)
3052 }
3053
3054 pub fn path(&self) -> String {
3057 self.inner.path()
3058 }
3059
3060 pub fn shape(&self) -> &'static Shape {
3062 self.inner.shape()
3063 }
3064
3065 pub fn set_nth_element<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
3067 where
3068 U: Facet<'facet>,
3069 {
3070 self.inner.set_nth_element(idx, value)?;
3071 Ok(self)
3072 }
3073
3074 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
3076 where
3077 U: Facet<'facet>,
3078 {
3079 self.inner.set_nth_field(idx, value)?;
3080 Ok(self)
3081 }
3082
3083 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
3085 where
3086 U: Facet<'facet>,
3087 {
3088 self.inner.set_field(field_name, value)?;
3089 Ok(self)
3090 }
3091
3092 pub fn set_nth_enum_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
3094 where
3095 U: Facet<'facet>,
3096 {
3097 self.inner.set_nth_enum_field(idx, value)?;
3098 Ok(self)
3099 }
3100
3101 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
3103 where
3104 U: Facet<'facet>,
3105 {
3106 self.inner.set_key(value)?;
3107 Ok(self)
3108 }
3109
3110 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
3112 where
3113 U: Facet<'facet>,
3114 {
3115 self.inner.set_value(value)?;
3116 Ok(self)
3117 }
3118
3119 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
3121 where
3122 U: Facet<'facet>,
3123 {
3124 self.inner.push(value)?;
3125 Ok(self)
3126 }
3127
3128 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
3130 self.inner.begin_some()?;
3131 Ok(self)
3132 }
3133
3134 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
3136 self.inner.begin_inner()?;
3137 Ok(self)
3138 }
3139}
3140
3141impl<'facet, T> core::fmt::Debug for TypedPartial<'facet, T> {
3142 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3143 f.debug_struct("TypedPartial")
3144 .field("shape", &self.inner.frames.last().map(|frame| frame.shape))
3145 .finish()
3146 }
3147}
3148
3149impl<'facet> Drop for Partial<'facet> {
3150 fn drop(&mut self) {
3151 trace!("🧹 Partial is being dropped");
3152
3153 while let Some(frame) = self.frames.pop() {
3155 match &frame.tracker {
3156 Tracker::Uninit => {
3157 }
3159 Tracker::Init => {
3160 if let Some(drop_fn) =
3162 frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3163 {
3164 unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3165 }
3166 }
3167 Tracker::Array { iset, .. } => {
3168 if let Type::Sequence(facet_core::SequenceType::Array(array_def)) =
3170 frame.shape.ty
3171 {
3172 let element_layout = array_def.t.layout.sized_layout().ok();
3173 if let Some(layout) = element_layout {
3174 for idx in 0..array_def.n {
3175 if iset.get(idx) {
3176 let offset = layout.size() * idx;
3177 let element_ptr = unsafe { frame.data.field_init_at(offset) };
3178 if let Some(drop_fn) =
3179 array_def.t.vtable.sized().and_then(|v| (v.drop_in_place)())
3180 {
3181 unsafe { drop_fn(element_ptr) };
3182 }
3183 }
3184 }
3185 }
3186 }
3187 }
3188 Tracker::Struct { iset, .. } => {
3189 if let Type::User(UserType::Struct(struct_type)) = frame.shape.ty {
3191 for (idx, field) in struct_type.fields.iter().enumerate() {
3192 if iset.get(idx) {
3193 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
3195 if let Some(drop_fn) =
3196 field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3197 {
3198 unsafe { drop_fn(field_ptr) };
3199 }
3200 }
3201 }
3202 }
3203 }
3204 Tracker::Enum { variant, data, .. } => {
3205 for (idx, field) in variant.data.fields.iter().enumerate() {
3207 if data.get(idx) {
3208 let field_ptr =
3210 unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
3211 if let Some(drop_fn) =
3212 field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3213 {
3214 unsafe { drop_fn(PtrMut::new(field_ptr)) };
3215 }
3216 }
3217 }
3218 }
3219 Tracker::SmartPointer { is_initialized } => {
3220 if *is_initialized {
3222 if let Some(drop_fn) =
3223 frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3224 {
3225 unsafe { drop_fn(frame.data.assume_init()) };
3226 }
3227 }
3228 }
3231 Tracker::SmartPointerStr { is_initialized } => {
3232 if *is_initialized {
3234 if let Some(drop_fn) =
3235 frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3236 {
3237 unsafe { drop_fn(frame.data.assume_init()) };
3238 }
3239 }
3240 }
3241 Tracker::SmartPointerSlice { vtable, .. } => {
3242 let builder_ptr = unsafe { frame.data.assume_init() };
3244 unsafe {
3245 (vtable.free_fn)(builder_ptr);
3246 }
3247 }
3248 Tracker::List { is_initialized, .. } => {
3249 if *is_initialized {
3251 if let Some(drop_fn) =
3252 frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3253 {
3254 unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3255 }
3256 }
3257 }
3258 Tracker::Map {
3259 is_initialized,
3260 insert_state,
3261 } => {
3262 if *is_initialized {
3264 if let Some(drop_fn) =
3265 frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3266 {
3267 unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3268 }
3269 }
3270
3271 match insert_state {
3273 MapInsertState::PushingKey { key_ptr } => {
3274 if let Some(key_ptr) = key_ptr {
3275 if let Def::Map(map_def) = frame.shape.def {
3277 if let Ok(key_shape) = map_def.k().layout.sized_layout() {
3278 if key_shape.size() > 0 {
3279 unsafe {
3280 alloc::alloc::dealloc(
3281 key_ptr.as_mut_byte_ptr(),
3282 key_shape,
3283 )
3284 };
3285 }
3286 }
3287 }
3288 }
3289 }
3290 MapInsertState::PushingValue { key_ptr, value_ptr } => {
3291 if let Def::Map(map_def) = frame.shape.def {
3293 if let Some(drop_fn) =
3295 map_def.k().vtable.sized().and_then(|v| (v.drop_in_place)())
3296 {
3297 unsafe { drop_fn(PtrMut::new(key_ptr.as_mut_byte_ptr())) };
3298 }
3299 if let Ok(key_shape) = map_def.k().layout.sized_layout() {
3300 if key_shape.size() > 0 {
3301 unsafe {
3302 alloc::alloc::dealloc(
3303 key_ptr.as_mut_byte_ptr(),
3304 key_shape,
3305 )
3306 };
3307 }
3308 }
3309
3310 if let Some(value_ptr) = value_ptr {
3312 if let Ok(value_shape) = map_def.v().layout.sized_layout() {
3313 if value_shape.size() > 0 {
3314 unsafe {
3315 alloc::alloc::dealloc(
3316 value_ptr.as_mut_byte_ptr(),
3317 value_shape,
3318 )
3319 };
3320 }
3321 }
3322 }
3323 }
3324 }
3325 MapInsertState::Idle => {}
3326 }
3327 }
3328 Tracker::Option { building_inner } => {
3329 if !building_inner {
3333 if let Some(drop_fn) =
3335 frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3336 {
3337 unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3338 }
3339 }
3340 }
3341 }
3342
3343 if let FrameOwnership::Owned = frame.ownership {
3345 if let Ok(layout) = frame.shape.layout.sized_layout() {
3346 if layout.size() > 0 {
3347 unsafe { alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout) };
3348 }
3349 }
3350 }
3351 }
3352 }
3353}