1use crate::{ReflectError, ValueId};
2use crate::{debug, trace};
3#[cfg(feature = "log")]
4use alloc::string::ToString;
5#[cfg(feature = "log")]
6use owo_colors::OwoColorize;
7
8use alloc::format;
9use alloc::{vec, vec::Vec};
10use bitflags::bitflags;
11use core::{fmt, marker::PhantomData};
12use facet_core::{
13 Def, DefaultInPlaceFn, Facet, FieldError, PtrConst, PtrMut, PtrUninit, ScalarAffinity, Shape,
14 Variant,
15};
16use flat_map::FlatMap;
17
18use alloc::string::String;
19
20mod iset;
21pub use iset::*;
22
23mod put_f64;
24
25mod enum_;
26mod flat_map;
27
28mod heap_value;
29pub use heap_value::*;
30
31fn def_kind(def: &Def) -> &'static str {
32 match def {
33 Def::Scalar(_) => "scalar",
34 Def::Struct(_) => "struct",
35 Def::Map(_) => "map",
36 Def::List(_) => "list",
37 Def::Enum(_) => "enum",
38 Def::Option(_) => "option",
39 Def::SmartPointer(_) => "smart_ptr",
40 _ => "other",
41 }
42}
43
44pub struct Frame {
46 data: PtrUninit<'static>,
48
49 shape: &'static Shape,
51
52 field_index_in_parent: Option<usize>,
55
56 istate: IState,
60}
61
62impl Frame {
63 fn recompose(id: ValueId, istate: IState) -> Self {
65 Frame {
66 data: PtrUninit::new(id.ptr as *mut u8),
67 shape: id.shape,
68 field_index_in_parent: None,
69 istate,
70 }
71 }
72
73 fn dealloc_if_needed(&mut self) {
75 if self.istate.flags.contains(FrameFlags::ALLOCATED) {
76 trace!(
77 "[{}] {:p} => deallocating {}",
78 self.istate.depth,
79 self.data.as_mut_byte_ptr().magenta(),
80 self.shape.green(),
81 );
82 match self.shape.layout {
83 facet_core::ShapeLayout::Sized(layout) => {
84 if layout.size() != 0 {
85 unsafe {
86 alloc::alloc::dealloc(self.data.as_mut_byte_ptr(), layout);
87 }
88 }
89 }
90 facet_core::ShapeLayout::Unsized => unimplemented!(),
91 }
92 self.istate.flags.remove(FrameFlags::ALLOCATED);
93 } else {
94 trace!(
95 "[{}] {:p} => NOT deallocating {} (not ALLOCATED)",
96 self.istate.depth,
97 self.data.as_mut_byte_ptr().magenta(),
98 self.shape.green(),
99 );
100 }
101 }
102}
103
104struct DebugToDisplay<T>(T);
105
106impl<T> fmt::Debug for DebugToDisplay<T>
107where
108 T: fmt::Display,
109{
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 fmt::Display::fmt(&self.0, f)
112 }
113}
114
115impl fmt::Debug for Frame {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.debug_struct("Frame")
118 .field("shape", &DebugToDisplay(&self.shape))
119 .field("kind", &def_kind(&self.shape.def))
120 .field("index", &self.field_index_in_parent)
121 .field("mode", &self.istate.mode)
122 .field("id", &self.id())
123 .finish()
124 }
125}
126
127impl Frame {
128 fn id(&self) -> ValueId {
130 ValueId::new(self.shape, self.data.as_byte_ptr())
131 }
132
133 fn is_fully_initialized(&self) -> bool {
135 match self.shape.def {
136 Def::Struct(sd) => self.istate.fields.are_all_set(sd.fields.len()),
137 Def::Enum(_) => match self.istate.variant.as_ref() {
138 None => false,
139 Some(v) => self.istate.fields.are_all_set(v.data.fields.len()),
140 },
141 _ => self.istate.fields.are_all_set(1),
142 }
143 }
144
145 unsafe fn drop_and_dealloc_if_needed(mut self) {
147 trace!(
148 "[Frame::drop] Dropping frame for shape {} at {:p}",
149 self.shape.blue(),
150 self.data.as_byte_ptr()
151 );
152 if let Some(drop_in_place) = self.shape.vtable.drop_in_place {
153 unsafe {
154 trace!(
155 "[Frame::drop] Invoking drop_in_place for shape {} at {:p}",
156 self.shape.green(),
157 self.data.as_byte_ptr()
158 );
159 drop_in_place(self.data.assume_init());
160 }
161 } else {
162 trace!(
163 "[Frame::drop] No drop_in_place function for shape {}",
164 self.shape.blue(),
165 );
166 }
167 self.dealloc_if_needed();
168 }
169
170 unsafe fn mark_fully_initialized(&mut self) {
172 match self.shape.def {
173 Def::Struct(sd) => {
174 self.istate.fields = ISet::all(sd.fields);
175 }
176 Def::Enum(_) => {
177 if let Some(variant) = &self.istate.variant {
178 self.istate.fields = ISet::all(variant.data.fields);
179 }
180 }
181 _ => {
182 self.istate.fields.set(0);
183 }
184 }
185 }
186}
187
188struct IState {
190 variant: Option<Variant>,
192
193 fields: ISet,
195
196 depth: usize,
198
199 mode: FrameMode,
201
202 flags: FrameFlags,
204
205 list_index: Option<usize>,
207
208 #[allow(dead_code)]
210 map_key: Option<String>,
211}
212
213bitflags! {
214 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
216 pub struct FrameFlags: u64 {
217 const EMPTY = 0;
219
220 const ALLOCATED = 1 << 0;
222
223 const MOVED = 1 << 1;
227 }
228
229 }
231
232impl IState {
233 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
235 Self {
236 variant: None,
237 fields: Default::default(),
238 depth,
239 mode,
240 flags,
241 list_index: None,
242 map_key: None,
243 }
244 }
245
246 #[allow(dead_code)]
248 pub fn with_list_index(mut self, index: usize) -> Self {
249 self.list_index = Some(index);
250 self
251 }
252
253 #[allow(dead_code)]
255 pub fn with_map_key(mut self, key: String) -> Self {
256 self.map_key = Some(key);
257 self
258 }
259}
260
261#[derive(Debug, Clone, Copy, PartialEq, Eq)]
263pub enum FrameMode {
264 Root,
266 Field,
268 ListElement,
270 MapKey,
272 MapValue {
274 index: usize,
276 },
277 OptionSome,
279 OptionNone,
282}
283
284pub struct Wip<'facet_lifetime> {
286 frames: alloc::vec::Vec<Frame>,
288
289 istates: FlatMap<ValueId, IState>,
291
292 invariant: PhantomData<fn(&'facet_lifetime ()) -> &'facet_lifetime ()>,
293}
294
295impl<'facet_lifetime> Wip<'facet_lifetime> {
296 pub fn put_peek(
298 self,
299 peek: crate::Peek<'_, 'facet_lifetime>,
300 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
301 self.put_shape(peek.data, peek.shape)
302 }
303
304 pub fn frames_count(&self) -> usize {
306 self.frames.len()
307 }
308
309 pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
311 let data = shape
312 .allocate()
313 .map_err(|_| ReflectError::Unsized { shape })?;
314 Ok(Self {
315 frames: alloc::vec![Frame {
316 data,
317 shape,
318 field_index_in_parent: None,
319 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
320 }],
321 istates: Default::default(),
322 invariant: PhantomData,
323 })
324 }
325
326 pub fn alloc<S: Facet<'facet_lifetime>>() -> Result<Self, ReflectError> {
328 Self::alloc_shape(S::SHAPE)
329 }
330
331 fn track(&mut self, frame: Frame) {
332 if frame.istate.flags.contains(FrameFlags::MOVED) {
338 return;
340 }
341
342 self.istates.insert(frame.id(), frame.istate);
343 }
344
345 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame) {
346 unsafe fn mark_subtree_moved(wip: &mut Wip, id: ValueId) {
349 unsafe {
351 if let Some(mut istate) = wip.istates.remove(&id) {
353 istate.flags.insert(FrameFlags::MOVED);
355
356 match id.shape.def {
358 Def::Struct(sd) => {
359 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
360 for field in sd.fields.iter() {
361 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
362 let field_id =
363 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
364 mark_subtree_moved(wip, field_id);
366 }
367 }
368 Def::Enum(_) => {
369 if let Some(variant) = &istate.variant {
371 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
372 for field in variant.data.fields.iter() {
373 let field_ptr_uninit =
374 container_ptr.field_uninit_at(field.offset);
375 let field_id =
376 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
377 mark_subtree_moved(wip, field_id);
379 }
380 }
381 }
382 _ => {}
386 }
387
388 if istate.flags.contains(FrameFlags::ALLOCATED) {
391 let mut temp_frame = Frame::recompose(id, istate);
393 temp_frame.dealloc_if_needed();
394 }
395 }
396 }
398 }
399
400 unsafe {
403 let frame_id = frame.id();
405
406 let variant_opt = frame.istate.variant;
408
409 frame.istate.flags.insert(FrameFlags::MOVED);
411 ISet::clear(&mut frame.istate.fields);
412
413 match frame.shape.def {
416 Def::Struct(sd) => {
417 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
418 for field in sd.fields.iter() {
419 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
420 let field_id = ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
421 mark_subtree_moved(self, field_id);
422 }
423 }
424 Def::Enum(_) => {
425 if let Some(variant) = &variant_opt {
427 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
428 for field in variant.data.fields.iter() {
429 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
430 let field_id =
431 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
432 mark_subtree_moved(self, field_id);
433 }
434 }
435 }
436 _ => {}
438 }
439
440 frame.istate.variant = None;
442
443 self.istates.remove(&frame_id);
445
446 if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
448 frame.dealloc_if_needed();
449 }
450 }
451 }
452
453 pub fn shape(&self) -> &'static Shape {
455 self.frames.last().expect("must have frames left").shape
456 }
457
458 pub fn innermost_shape(&self) -> &'static Shape {
462 let mut current_shape = self.shape();
463
464 while let Some(inner_fn) = current_shape.inner {
466 current_shape = inner_fn();
467 }
468
469 current_shape
470 }
471
472 pub fn in_option(&self) -> bool {
474 let Some(frame) = self.frames.last() else {
475 return false;
476 };
477 matches!(frame.istate.mode, FrameMode::OptionSome)
478 }
479
480 pub fn mode(&self) -> FrameMode {
482 self.frames.last().unwrap().istate.mode
483 }
484
485 pub fn build(mut self) -> Result<HeapValue<'facet_lifetime>, ReflectError> {
487 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
488
489 if self.frames.is_empty() {
491 panic!("No frames in WIP during build: stack is empty (you popped too much)");
492 }
493 if self.frames.len() != 1 {
494 panic!(
495 "You must pop frames so that only the root frame remains before calling build (frames left: {})",
496 self.frames.len()
497 );
498 }
499
500 let root_frame = &self.frames[0];
502
503 enum FrameRef {
504 Root,
505 ById(ValueId),
506 }
507 let mut to_check = alloc::vec![FrameRef::Root];
508
509 while let Some(fr) = to_check.pop() {
511 let (id, istate) = match fr {
512 FrameRef::Root => (root_frame.id(), &root_frame.istate),
513 FrameRef::ById(id) => {
514 let istate = self.istates.get(&id).unwrap();
516 (id, istate)
517 }
518 };
519
520 trace!(
521 "Checking shape {} at {:p}, flags={:?}, mode={:?}",
522 id.shape.blue(),
523 id.ptr,
524 istate.flags.bright_magenta(),
525 istate.mode,
526 );
527
528 if istate.flags.contains(FrameFlags::MOVED) {
530 trace!(
531 "{}",
532 "Frame was moved out of, skipping initialization check".yellow()
533 );
534 continue;
535 }
536
537 match id.shape.def {
539 Def::Struct(sd) => {
540 for i in 0..sd.fields.len() {
542 if !istate.fields.has(i) {
543 let field = &sd.fields[i];
544 return Err(ReflectError::UninitializedField {
545 shape: id.shape,
546 field_name: field.name,
547 });
548 }
549 }
550
551 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
552
553 #[allow(clippy::unused_enumerate_index)]
555 for (_i, field) in sd.fields.iter().enumerate() {
556 let field_shape = field.shape();
557 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
558 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
559
560 if self.istates.contains_key(&field_id) {
561 debug!(
562 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
563 _i.to_string().bright_cyan(),
564 field.name.bright_blue(),
565 id.shape.blue(),
566 field_shape.green(),
567 field_ptr.as_byte_ptr()
568 );
569 to_check.push(FrameRef::ById(field_id));
570 }
571 }
572 }
573 Def::Enum(_ed) => {
574 if let Some(variant) = &istate.variant {
575 for (i, field) in variant.data.fields.iter().enumerate() {
577 if !istate.fields.has(i) {
578 return Err(ReflectError::UninitializedEnumField {
579 shape: id.shape,
580 variant_name: variant.name,
581 field_name: field.name,
582 });
583 }
584 }
585
586 #[allow(clippy::unused_enumerate_index)]
588 for (_i, field) in variant.data.fields.iter().enumerate() {
589 let field_shape = field.shape();
590 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
591 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
593 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
594
595 if self.istates.contains_key(&field_id) {
596 debug!(
597 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
598 _i.to_string().bright_cyan(),
599 field.name.bright_blue(),
600 variant.name.yellow(),
601 id.shape.blue(),
602 field_shape.green(),
603 field_ptr.as_byte_ptr()
604 );
605 to_check.push(FrameRef::ById(field_id));
606 }
607 }
608 } else {
609 debug!("Found no variant selected for enum");
611 return Err(ReflectError::NoVariantSelected { shape: id.shape });
612 }
613 }
614 Def::List(_)
618 | Def::Map(_)
619 | Def::Option(_)
620 | Def::Scalar(_)
621 | Def::FunctionPointer(_)
622 | Def::SmartPointer(_)
623 | Def::Array(_)
624 | Def::Slice(_) => {
625 if !istate.fields.are_all_set(1) {
626 match istate.mode {
628 FrameMode::OptionNone => {
629 debug!("Found uninitialized value (option none)");
631 return Err(ReflectError::UninitializedValue { shape: id.shape });
632 }
633 _ => {
635 debug!("Found uninitialized value (list/map/option/etc.)");
636 return Err(ReflectError::UninitializedValue { shape: id.shape });
637 }
638 }
639 }
640 }
648 _ => {
650 if !istate.fields.are_all_set(1) {
652 debug!("Found uninitialized value (other)");
653 return Err(ReflectError::UninitializedValue { shape: id.shape });
654 }
655 }
656 }
657 }
658
659 debug!("All reachable frames checked and initialized.");
661
662 let root_shape = root_frame.shape;
665 let root_data = unsafe { root_frame.data.assume_init() };
666 if let Some(invariant_fn) = root_shape.vtable.invariants {
667 debug!(
668 "Checking invariants for root shape {} at {:p}",
669 root_shape.green(),
670 root_data.as_byte_ptr()
671 );
672 if !unsafe { invariant_fn(PtrConst::new(root_data.as_byte_ptr())) } {
673 return Err(ReflectError::InvariantViolation {
674 invariant: "Custom validation function returned false",
675 });
676 }
677 } else {
678 debug!(
679 "No invariants to check for root shape {}",
680 root_shape.blue()
681 );
682 }
683
684 {
686 FlatMap::clear(&mut self.istates);
687 self.frames.clear();
688 }
689
690 let guard = Guard {
692 ptr: root_data.as_mut_byte_ptr(),
693 layout: match root_shape.layout {
694 facet_core::ShapeLayout::Sized(layout) => layout,
695 facet_core::ShapeLayout::Unsized => panic!("Unsized layout not supported"),
696 },
697 };
698
699 Ok(HeapValue {
700 guard: Some(guard),
701 shape: root_shape,
702 phantom: PhantomData,
703 })
704 }
705
706 pub fn field(mut self, index: usize) -> Result<Self, ReflectError> {
718 let frame = self.frames.last_mut().unwrap();
719 let shape = frame.shape;
720
721 let (field, field_offset) = match shape.def {
722 Def::Struct(def) => {
723 if index >= def.fields.len() {
724 return Err(ReflectError::FieldError {
725 shape,
726 field_error: FieldError::NoSuchField,
727 });
728 }
729 let field = &def.fields[index];
730 (field, field.offset)
731 }
732 Def::Enum(_) => {
733 let Some(variant) = frame.istate.variant.as_ref() else {
734 return Err(ReflectError::OperationFailed {
735 shape,
736 operation: "tried to access a field but no variant was selected",
737 });
738 };
739
740 if index >= variant.data.fields.len() {
741 return Err(ReflectError::FieldError {
742 shape,
743 field_error: FieldError::NoSuchField,
744 });
745 }
746
747 let field = &variant.data.fields[index];
748 (field, field.offset)
749 }
750 _ => {
751 return Err(ReflectError::WasNotA {
752 expected: "struct or enum",
753 actual: shape,
754 });
755 }
756 };
757
758 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
759
760 let mut frame = Frame {
761 data: field_data,
762 shape: field.shape(),
763 field_index_in_parent: Some(index),
764 istate: IState::new(self.frames.len(), FrameMode::Field, FrameFlags::EMPTY),
766 };
767 debug!(
768 "[{}] Selecting field {} ({}#{}) of {}",
769 self.frames.len(),
770 field.name.blue(),
771 field.shape().green(),
772 index.yellow(),
773 shape.blue(),
774 );
775 if let Some(iset) = self.istates.remove(&frame.id()) {
776 trace!(
777 "[{}] Restoring saved state for {} (istate.mode = {:?}, istate.fields = {:?}, istate.flags = {:?}, istate.depth = {:?})",
778 self.frames.len(),
779 frame.id().shape.blue(),
780 iset.mode,
781 iset.fields,
782 iset.flags,
783 iset.depth
784 );
785 frame.istate = iset;
786 } else {
787 trace!(
788 "[{}] no saved state for field {} ({}#{}) of {}",
789 self.frames.len(),
790 field.name.blue(),
791 field.shape().green(),
792 index.yellow(),
793 shape.blue(),
794 );
795 }
796 self.frames.push(frame);
797 Ok(self)
798 }
799
800 pub fn field_index(&self, name: &str) -> Option<usize> {
812 fn find_field_index(fields: &'static [facet_core::Field], name: &str) -> Option<usize> {
813 fields
814 .iter()
815 .position(|f| f.get_rename_attr().unwrap_or(f.name) == name)
816 }
817
818 let frame = self.frames.last()?;
819 match frame.shape.def {
820 Def::Struct(def) => find_field_index(def.fields, name),
821 Def::Enum(_) => {
822 let variant = frame.istate.variant.as_ref()?;
823 find_field_index(variant.data.fields, name)
824 }
825 _ => None,
826 }
827 }
828
829 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
841 let frame = self.frames.last().unwrap();
842 let shape = frame.shape;
843
844 if let Def::Enum(_) = shape.def {
846 if frame.istate.variant.is_none() {
847 return Err(ReflectError::OperationFailed {
848 shape,
849 operation: "tried to access a field by name but no variant was selected",
850 });
851 }
852 }
853
854 let index = self.field_index(name).ok_or(ReflectError::FieldError {
855 shape,
856 field_error: FieldError::NoSuchField,
857 })?;
858
859 self.field(index)
860 }
861
862 pub fn put<T: Facet<'facet_lifetime>>(
873 self,
874 t: T,
875 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
876 let shape = T::SHAPE;
877 let ptr_const = PtrConst::new(&t as *const T as *const u8);
878 let res = self.put_shape(ptr_const, shape);
879 core::mem::forget(t); res
881 }
882
883 pub fn try_put<T: Facet<'facet_lifetime>>(
894 self,
895 t: T,
896 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
897 let shape = T::SHAPE;
898 let ptr_const = PtrConst::new(&t as *const T as *const u8);
899 let res = self.put_shape(ptr_const, shape);
900 core::mem::forget(t); res
902 }
903
904 pub fn put_shape(
906 mut self,
907 src: PtrConst<'_>,
908 src_shape: &'static Shape,
909 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
910 let Some(frame) = self.frames.last_mut() else {
911 return Err(ReflectError::OperationFailed {
912 shape: src_shape,
913 operation: "tried to put a value but there was no frame to put into",
914 });
915 };
916
917 if frame.shape != src_shape {
919 trace!(
920 "Trying to put a {} into a {}",
921 src_shape.yellow(),
922 frame.shape.magenta()
923 );
924
925 if let Some(inner_fn) = frame.shape.inner {
927 let inner_shape = inner_fn();
929
930 if src_shape == inner_shape {
932 if let Some(try_from_fn) = frame.shape.vtable.try_from {
934 match unsafe { (try_from_fn)(src, src_shape, frame.data) } {
935 Ok(_) => {
936 unsafe {
937 frame.mark_fully_initialized();
938 }
939
940 let shape = frame.shape;
941 let index = frame.field_index_in_parent;
942
943 self.mark_field_as_initialized(shape, index)?;
945
946 debug!(
947 "[{}] Just put a {} value into transparent type {}",
948 self.frames.len(),
949 src_shape.green(),
950 shape.blue()
951 );
952
953 return Ok(self);
954 }
955 Err(e) => {
956 return Err(ReflectError::TryFromError {
957 inner: e,
958 src_shape,
959 dst_shape: frame.shape,
960 });
961 }
962 }
963 } else {
964 debug!(
966 "No try_from_inner function for transparent type, falling back to TryFrom"
967 );
968 }
969 }
970 }
971
972 if let Some(try_from) = frame.shape.vtable.try_from {
974 match unsafe { try_from(src, src_shape, frame.data) } {
975 Ok(_) => {
976 unsafe {
977 frame.mark_fully_initialized();
978 }
979
980 let shape = frame.shape;
981 let index = frame.field_index_in_parent;
982
983 self.mark_field_as_initialized(shape, index)?;
985
986 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
987
988 return Ok(self);
989 }
990 Err(e) => {
991 return Err(ReflectError::TryFromError {
992 inner: e,
993 src_shape,
994 dst_shape: frame.shape,
995 });
996 }
997 }
998 }
999
1000 if let Def::Option(od) = frame.shape.def {
1003 if od.t() == src_shape {
1005 debug!("Putting into an Option<T>!");
1006 if frame.istate.fields.is_any_set() {
1007 let data = unsafe { frame.data.assume_init() };
1008 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
1009 } else {
1010 let data = frame.data;
1011 unsafe { (od.vtable.init_some_fn)(data, src) };
1012 }
1013 unsafe {
1014 frame.mark_fully_initialized();
1015 }
1016
1017 let shape = frame.shape;
1018 let index = frame.field_index_in_parent;
1019
1020 self.mark_field_as_initialized(shape, index)?;
1022
1023 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1024
1025 return Ok(self);
1026 }
1027 }
1028
1029 if let Def::Struct(sd) = frame.shape.def {
1033 for (i, field) in sd.fields.iter().enumerate() {
1035 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1036 debug!(
1037 "Found uninitialized field {} with matching type {}",
1038 i.to_string().blue(),
1039 src_shape.green()
1040 );
1041
1042 unsafe {
1044 let field_data = frame.data.field_uninit_at(field.offset);
1045 field_data.copy_from(src, field.shape()).map_err(|_| {
1046 ReflectError::Unsized {
1047 shape: field.shape(),
1048 }
1049 })?;
1050 frame.istate.fields.set(i);
1051 }
1052
1053 let shape = frame.shape;
1054 let index = frame.field_index_in_parent;
1055
1056 if frame.is_fully_initialized() {
1058 self.mark_field_as_initialized(shape, index)?;
1059 }
1060
1061 debug!(
1062 "[{}] Put a {} value into field {} of {}",
1063 self.frames.len(),
1064 src_shape.green(),
1065 i.to_string().blue(),
1066 shape.green()
1067 );
1068
1069 return Ok(self);
1070 }
1071 }
1072 }
1073
1074 if let Def::Enum(_) = frame.shape.def {
1077 if let Some(variant) = &frame.istate.variant {
1079 for (i, field) in variant.data.fields.iter().enumerate() {
1081 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1082 debug!(
1083 "Found uninitialized field {} in enum variant '{}' with matching type {}",
1084 i.to_string().blue(),
1085 variant.name.bright_yellow(),
1086 src_shape.green()
1087 );
1088
1089 unsafe {
1091 let field_data = frame.data.field_uninit_at(field.offset);
1092 field_data.copy_from(src, field.shape()).map_err(|_| {
1093 ReflectError::Unsized {
1094 shape: field.shape(),
1095 }
1096 })?;
1097 frame.istate.fields.set(i);
1098 }
1099
1100 let shape = frame.shape;
1101 let index = frame.field_index_in_parent;
1102
1103 #[allow(unused)]
1104 let variant_name = variant.name;
1105
1106 if frame.is_fully_initialized() {
1108 self.mark_field_as_initialized(shape, index)?;
1109 }
1110
1111 debug!(
1112 "[{}] Put a {} value into field {} of variant '{}' in enum {}",
1113 self.frames.len(),
1114 src_shape.green(),
1115 i.to_string().blue(),
1116 variant_name.bright_yellow(),
1117 shape.green()
1118 );
1119
1120 return Ok(self);
1121 }
1122 }
1123 }
1124 }
1125
1126 return Err(ReflectError::WrongShape {
1127 expected: frame.shape,
1128 actual: src_shape,
1129 });
1130 }
1131
1132 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
1134 debug!("De-initializing partially initialized {:?}", frame.yellow());
1135
1136 match frame.shape.def {
1137 Def::Struct(sd) => {
1138 for (i, field) in sd.fields.iter().enumerate() {
1139 if frame.istate.fields.has(i) {
1140 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1141 unsafe {
1142 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
1143 drop_fn(PtrMut::new(field_ptr));
1144 }
1145 }
1146 }
1147 }
1148 }
1149 Def::Enum(_) => {
1150 if let Some(variant) = &frame.istate.variant {
1151 for (i, field) in variant.data.fields.iter().enumerate() {
1152 if frame.istate.fields.has(i) {
1153 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1154 unsafe {
1155 let field_ptr =
1156 frame.data.as_mut_byte_ptr().add(field.offset);
1157 drop_fn(PtrMut::new(field_ptr));
1158 }
1159 }
1160 }
1161 }
1162 }
1163 }
1164 _ => {
1165 if frame.istate.fields.is_any_set() {
1167 debug!("Scalar type was set...");
1168 if let Some(drop_fn) = frame.shape.vtable.drop_in_place {
1169 debug!("And it has a drop fn, dropping now!");
1170 unsafe {
1171 drop_fn(frame.data.assume_init());
1172 }
1173 }
1174 }
1175 }
1176 }
1177
1178 frame.istate.variant = None;
1180 ISet::clear(&mut frame.istate.fields);
1181 }
1182
1183 unsafe {
1184 frame
1186 .data
1187 .copy_from(src, frame.shape)
1188 .map_err(|_| ReflectError::Unsized { shape: frame.shape })?;
1189 frame.mark_fully_initialized();
1190 }
1191
1192 let shape = frame.shape;
1193 let index = frame.field_index_in_parent;
1194
1195 self.mark_field_as_initialized(shape, index)?;
1197
1198 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1199
1200 Ok(self)
1201 }
1202
1203 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
1205 let Some(frame) = self.frames.last_mut() else {
1206 return Err(ReflectError::OperationFailed {
1207 shape: <()>::SHAPE,
1208 operation: "tried to parse value but there was no frame",
1209 });
1210 };
1211
1212 let shape = frame.shape;
1213 let index = frame.field_index_in_parent;
1214
1215 let Some(parse_fn) = frame.shape.vtable.parse else {
1216 return Err(ReflectError::OperationFailed {
1217 shape: frame.shape,
1218 operation: "type does not implement Parse",
1219 });
1220 };
1221 match unsafe { (parse_fn)(s, frame.data) } {
1222 Ok(_res) => {
1223 unsafe {
1224 frame.mark_fully_initialized();
1225 }
1226
1227 self.mark_field_as_initialized(shape, index)?;
1229
1230 Ok(self)
1231 }
1232 Err(_) => Err(ReflectError::OperationFailed {
1233 shape,
1234 operation: "parsing",
1235 }),
1236 }
1237 }
1238
1239 pub fn put_from_fn(mut self, default_in_place: DefaultInPlaceFn) -> Result<Self, ReflectError> {
1241 let Some(frame) = self.frames.last_mut() else {
1242 return Err(ReflectError::OperationFailed {
1243 shape: <()>::SHAPE,
1244 operation: "tried to put value from fn but there was no frame",
1245 });
1246 };
1247
1248 unsafe {
1249 default_in_place(frame.data);
1250 frame.mark_fully_initialized();
1251 }
1252
1253 let shape = frame.shape;
1254 let index = frame.field_index_in_parent;
1255
1256 self.mark_field_as_initialized(shape, index)?;
1258
1259 Ok(self)
1260 }
1261
1262 pub fn put_default(self) -> Result<Self, ReflectError> {
1264 let Some(frame) = self.frames.last() else {
1265 return Err(ReflectError::OperationFailed {
1266 shape: <()>::SHAPE,
1267 operation: "tried to put default value but there was no frame",
1268 });
1269 };
1270
1271 let vtable = frame.shape.vtable;
1272 let Some(default_in_place) = vtable.default_in_place else {
1273 return Err(ReflectError::OperationFailed {
1274 shape: frame.shape,
1275 operation: "type does not implement Default",
1276 });
1277 };
1278
1279 self.put_from_fn(default_in_place)
1280 }
1281
1282 fn mark_field_as_initialized(
1284 &mut self,
1285 shape: &'static Shape,
1286 index: Option<usize>,
1287 ) -> Result<(), ReflectError> {
1288 if let Some(index) = index {
1289 let parent_index = self.frames.len().saturating_sub(2);
1290 #[cfg(feature = "log")]
1291 let num_frames = self.frames.len();
1292 let Some(parent) = self.frames.get_mut(parent_index) else {
1293 return Err(ReflectError::OperationFailed {
1294 shape,
1295 operation: "was supposed to mark a field as initialized, but there was no parent frame",
1296 });
1297 };
1298 #[cfg(feature = "log")]
1299 let parent_shape = parent.shape;
1300 trace!(
1301 "[{}] {}.{} initialized with {}",
1302 num_frames,
1303 parent_shape.blue(),
1304 index.yellow(),
1305 shape.green()
1306 );
1307
1308 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
1309 return Err(ReflectError::OperationFailed {
1310 shape,
1311 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
1312 });
1313 }
1314
1315 if parent.istate.fields.has(index) {
1316 return Err(ReflectError::OperationFailed {
1317 shape,
1318 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
1319 });
1320 }
1321
1322 parent.istate.fields.set(index);
1323 }
1324 Ok(())
1325 }
1326
1327 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
1329 let frame = self.frames.last().unwrap();
1330 let shape = frame.shape;
1331
1332 match shape.def {
1333 Def::List(list_def) => Ok(list_def.t()),
1334 _ => Err(ReflectError::WasNotA {
1335 expected: "list or array",
1336 actual: shape,
1337 }),
1338 }
1339 }
1340
1341 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
1343 let frame = self.frames.last().unwrap();
1344 let shape = frame.shape;
1345
1346 match shape.def {
1347 Def::Map(map_def) => Ok(map_def.k),
1348 _ => Err(ReflectError::WasNotA {
1349 expected: "map",
1350 actual: shape,
1351 }),
1352 }
1353 }
1354
1355 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
1357 let Some(frame) = self.frames.last_mut() else {
1358 return Err(ReflectError::OperationFailed {
1359 shape: <()>::SHAPE,
1360 operation: "tried to create empty list but there was no frame",
1361 });
1362 };
1363
1364 if !matches!(frame.shape.def, Def::List(_)) {
1365 return Err(ReflectError::WasNotA {
1366 expected: "list or array",
1367 actual: frame.shape,
1368 });
1369 }
1370
1371 let vtable = frame.shape.vtable;
1372
1373 let Some(default_in_place) = vtable.default_in_place else {
1375 return Err(ReflectError::OperationFailed {
1376 shape: frame.shape,
1377 operation: "list type does not implement Default",
1378 });
1379 };
1380
1381 unsafe {
1382 default_in_place(frame.data);
1383 frame.mark_fully_initialized();
1384 }
1385
1386 let shape = frame.shape;
1387 let index = frame.field_index_in_parent;
1388
1389 self.mark_field_as_initialized(shape, index)?;
1391
1392 Ok(self)
1393 }
1394
1395 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1397 let Some(frame) = self.frames.last_mut() else {
1398 return Err(ReflectError::OperationFailed {
1399 shape: <()>::SHAPE,
1400 operation: "tried to create empty map but there was no frame",
1401 });
1402 };
1403
1404 if !matches!(frame.shape.def, Def::Map(_)) {
1405 return Err(ReflectError::WasNotA {
1406 expected: "map or hash map",
1407 actual: frame.shape,
1408 });
1409 }
1410
1411 let vtable = frame.shape.vtable;
1412
1413 let Some(default_in_place) = vtable.default_in_place else {
1415 return Err(ReflectError::OperationFailed {
1416 shape: frame.shape,
1417 operation: "map type does not implement Default",
1418 });
1419 };
1420
1421 unsafe {
1422 default_in_place(frame.data);
1423 frame.mark_fully_initialized();
1424 }
1425
1426 let shape = frame.shape;
1427 let index = frame.field_index_in_parent;
1428
1429 self.mark_field_as_initialized(shape, index)?;
1431
1432 Ok(self)
1433 }
1434
1435 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1440 let Some(frame) = self.frames.last_mut() else {
1441 return Err(ReflectError::OperationFailed {
1442 shape: <()>::SHAPE,
1443 operation: "tried to begin pushback but there was no frame",
1444 });
1445 };
1446
1447 let is_list = matches!(frame.shape.def, Def::List(_));
1448 let is_tuple_struct_or_variant = match frame.shape.def {
1449 Def::Struct(sd) => sd.kind == facet_core::StructKind::Tuple,
1450 Def::Enum(_) => {
1451 if let Some(variant) = &frame.istate.variant {
1453 variant.data.kind == facet_core::StructKind::Tuple
1454 } else {
1455 false }
1464 }
1465 _ => false,
1466 };
1467
1468 if !is_list && !is_tuple_struct_or_variant {
1469 return Err(ReflectError::WasNotA {
1470 expected: "list, array, or tuple-like struct/enum variant",
1471 actual: frame.shape,
1472 });
1473 }
1474
1475 if is_list {
1477 let vtable = frame.shape.vtable;
1478 if !frame.istate.fields.has(0) {
1480 let Some(default_in_place) = vtable.default_in_place else {
1481 return Err(ReflectError::OperationFailed {
1482 shape: frame.shape,
1483 operation: "list type does not implement Default, cannot begin pushback",
1484 });
1485 };
1486
1487 unsafe {
1488 default_in_place(frame.data);
1489 frame.istate.fields.set(0);
1491 }
1492 }
1493 }
1494 Ok(self)
1497 }
1498
1499 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1501 let Some(frame) = self.frames.last_mut() else {
1502 return Err(ReflectError::OperationFailed {
1503 shape: <()>::SHAPE,
1504 operation: "tried to begin map insertion but there was no frame",
1505 });
1506 };
1507
1508 if !matches!(frame.shape.def, Def::Map(_)) {
1509 return Err(ReflectError::WasNotA {
1510 expected: "map or hash map",
1511 actual: frame.shape,
1512 });
1513 }
1514
1515 let vtable = frame.shape.vtable;
1516
1517 if !frame.istate.fields.has(0) {
1519 let Some(default_in_place) = vtable.default_in_place else {
1520 return Err(ReflectError::OperationFailed {
1521 shape: frame.shape,
1522 operation: "map type does not implement Default",
1523 });
1524 };
1525
1526 unsafe {
1527 default_in_place(frame.data);
1528 frame.istate.fields.set(0);
1529 }
1530 }
1531
1532 Ok(self)
1533 }
1534
1535 pub fn push(mut self) -> Result<Self, ReflectError> {
1540 let frame_len = self.frames.len();
1542 let frame = self
1543 .frames
1544 .last_mut()
1545 .ok_or(ReflectError::OperationFailed {
1546 shape: <()>::SHAPE,
1547 operation: "tried to push but there was no frame",
1548 })?;
1549 let seq_shape = frame.shape;
1550
1551 let (element_shape, context_str): (&'static Shape, &'static str) = match seq_shape.def {
1553 Def::List(_) => {
1554 if !frame.istate.fields.has(0) {
1556 return self.begin_pushback()?.push();
1559 }
1560 let shape = self.element_shape()?;
1563 (shape, "list")
1564 }
1565
1566 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
1567 let field_index = {
1569 let next_idx = frame.istate.list_index.unwrap_or(0);
1571 frame.istate.list_index = Some(next_idx + 1);
1572 next_idx
1573 };
1574 if field_index >= sd.fields.len() {
1576 return Err(ReflectError::FieldError {
1577 shape: seq_shape,
1578 field_error: FieldError::NoSuchField, });
1580 }
1581 (sd.fields[field_index].shape(), "tuple struct")
1583 }
1584
1585 Def::Enum(_) => {
1586 let variant =
1588 frame
1589 .istate
1590 .variant
1591 .as_ref()
1592 .ok_or(ReflectError::OperationFailed {
1593 shape: seq_shape,
1594 operation: "tried to push onto enum but no variant was selected",
1595 })?;
1596 if variant.data.kind != facet_core::StructKind::Tuple {
1598 return Err(ReflectError::WasNotA {
1599 expected: "tuple-like enum variant",
1600 actual: seq_shape, });
1602 }
1603 let field_index = {
1605 let next_idx = frame.istate.list_index.unwrap_or(0);
1607 frame.istate.list_index = Some(next_idx + 1);
1608 next_idx
1609 };
1610 if field_index >= variant.data.fields.len() {
1612 return Err(ReflectError::FieldError {
1613 shape: seq_shape, field_error: FieldError::NoSuchField,
1615 });
1616 }
1617 (
1619 variant.data.fields[field_index].shape(),
1620 "tuple enum variant",
1621 )
1622 }
1623
1624 _ => {
1625 return Err(ReflectError::WasNotA {
1627 expected: "list, array, tuple struct, or tuple enum variant",
1628 actual: seq_shape,
1629 });
1630 }
1631 };
1632
1633 let element_data = element_shape
1635 .allocate()
1636 .map_err(|_| ReflectError::Unsized {
1637 shape: element_shape,
1638 })?;
1639
1640 let element_frame = Frame {
1642 data: element_data,
1643 shape: element_shape,
1644 field_index_in_parent: None, istate: IState::new(
1646 frame_len, FrameMode::ListElement, FrameFlags::ALLOCATED,
1649 ),
1650 };
1651
1652 trace!(
1653 "[{}] Pushing element of type {} to {} {}",
1654 frame_len,
1655 element_shape.green(),
1656 context_str, seq_shape.blue(),
1658 );
1659 let _ = context_str;
1660
1661 self.frames.push(element_frame);
1662 Ok(self)
1663 }
1664
1665 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1667 let frame = self.frames.last().unwrap();
1669 let option_shape = frame.shape;
1670
1671 let Def::Option(option_def) = option_shape.def else {
1673 return Err(ReflectError::WasNotA {
1674 expected: "option",
1675 actual: option_shape,
1676 });
1677 };
1678
1679 let inner_shape = option_def.t();
1681
1682 let inner_data = inner_shape
1684 .allocate()
1685 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1686
1687 let inner_frame = Frame {
1689 data: inner_data,
1690 shape: inner_shape,
1691 field_index_in_parent: None,
1693 istate: IState::new(
1694 self.frames.len(),
1695 FrameMode::OptionSome,
1696 FrameFlags::ALLOCATED,
1698 ),
1699 };
1700
1701 trace!(
1702 "[{}] Pushing option frame for {}",
1703 self.frames.len(),
1704 option_shape.blue(),
1705 );
1706
1707 self.frames.push(inner_frame);
1708 Ok(self)
1709 }
1710
1711 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1721 let Some(frame) = self.frames.last_mut() else {
1723 return Err(ReflectError::OperationFailed {
1724 shape: <()>::SHAPE,
1725 operation: "tried to pop_some_push_none but there was no frame",
1726 });
1727 };
1728
1729 if frame.istate.mode != FrameMode::OptionSome {
1731 return Err(ReflectError::OperationFailed {
1732 shape: frame.shape,
1733 operation: "pop_some_push_none called, but frame was not in Option mode",
1734 });
1735 }
1736
1737 if frame.is_fully_initialized() {
1739 return Err(ReflectError::OperationFailed {
1740 shape: frame.shape,
1741 operation: "option frame already initialized, cannot pop_some_push_none",
1742 });
1743 }
1744
1745 frame.dealloc_if_needed();
1746
1747 let _frame = self.frames.pop().expect("frame already checked");
1749
1750 let parent_frame = self
1752 .frames
1753 .last_mut()
1754 .ok_or(ReflectError::OperationFailed {
1755 shape: <()>::SHAPE,
1756 operation: "tried to pop_some_push_none but there was no parent frame",
1757 })?;
1758
1759 unsafe {
1761 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1762 default_fn(parent_frame.data);
1763 } else {
1764 return Err(ReflectError::OperationFailed {
1765 shape: parent_frame.shape,
1766 operation: "option type does not implement Default",
1767 });
1768 }
1769 parent_frame.mark_fully_initialized();
1770 }
1771
1772 let Def::Option(od) = parent_frame.shape.def else {
1773 return Err(ReflectError::OperationFailed {
1774 shape: parent_frame.shape,
1775 operation: "pop_some_push_none and the parent isn't of type Option???",
1776 });
1777 };
1778
1779 let data = parent_frame.data;
1781
1782 let mut frame = Frame {
1783 data,
1784 shape: od.t(),
1785 field_index_in_parent: Some(0),
1786 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1787 };
1788 unsafe {
1789 frame.mark_fully_initialized();
1790 }
1791
1792 self.frames.push(frame);
1793
1794 Ok(self)
1795 }
1796
1797 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1802 let frame = self.frames.last().unwrap();
1804 let map_shape = frame.shape;
1805
1806 if !matches!(map_shape.def, Def::Map(_)) {
1807 return Err(ReflectError::WasNotA {
1808 expected: "map or hash map",
1809 actual: map_shape,
1810 });
1811 }
1812
1813 if !frame.istate.fields.has(0) {
1815 self = self.begin_map_insert()?;
1816 }
1817
1818 let key_shape = self.key_shape()?;
1820
1821 let key_data = key_shape
1823 .allocate()
1824 .map_err(|_| ReflectError::Unsized { shape: key_shape })?;
1825
1826 let key_frame = Frame {
1828 data: key_data,
1829 shape: key_shape,
1830 field_index_in_parent: None,
1831 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1832 };
1833
1834 trace!(
1835 "[{}] Pushing key of type {} for map {}",
1836 self.frames.len(),
1837 key_shape.green(),
1838 map_shape.blue(),
1839 );
1840
1841 self.frames.push(key_frame);
1842 Ok(self)
1843 }
1844
1845 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1850 trace!("Wants to push map value. Frames = ");
1851 #[cfg(feature = "log")]
1852 for (i, f) in self.frames.iter().enumerate() {
1853 trace!("Frame {}: {:?}", i, f);
1854 }
1855
1856 if self.frames.len() < 2 {
1858 return Err(ReflectError::OperationFailed {
1859 shape: <()>::SHAPE,
1860 operation: "tried to push map value but there was no key frame",
1861 });
1862 }
1863
1864 let key_frame_index = self.frames.len() - 1;
1866 let key_frame = &self.frames[key_frame_index];
1867
1868 match key_frame.istate.mode {
1870 FrameMode::MapKey => {} _ => {
1872 return Err(ReflectError::OperationFailed {
1873 shape: key_frame.shape,
1874 operation: "current frame is not a map key",
1875 });
1876 }
1877 }
1878
1879 if !key_frame.is_fully_initialized() {
1881 return Err(ReflectError::OperationFailed {
1882 shape: key_frame.shape,
1883 operation: "map key is not fully initialized",
1884 });
1885 }
1886
1887 let map_frame_index = self.frames.len() - 2;
1889 let map_frame = &self.frames[map_frame_index];
1890 let map_shape = map_frame.shape;
1891
1892 let Def::Map(map_def) = map_shape.def else {
1893 return Err(ReflectError::WasNotA {
1894 expected: "map",
1895 actual: map_frame.shape,
1896 });
1897 };
1898
1899 let value_shape = map_def.v;
1900
1901 let value_data = value_shape
1903 .allocate()
1904 .map_err(|_| ReflectError::Unsized { shape: value_shape })?;
1905
1906 let value_frame = Frame {
1908 data: value_data,
1909 shape: value_shape,
1910 field_index_in_parent: None,
1911 istate: IState::new(
1912 self.frames.len(),
1913 FrameMode::MapValue {
1914 index: key_frame_index,
1915 },
1916 FrameFlags::ALLOCATED,
1917 ),
1918 };
1919
1920 trace!(
1921 "[{}] Pushing value of type {} for map {} with key type {}",
1922 self.frames.len(),
1923 value_shape.green(),
1924 map_shape.blue(),
1925 key_frame.shape.yellow(),
1926 );
1927
1928 self.frames.push(value_frame);
1929 Ok(self)
1930 }
1931
1932 pub fn pop(mut self) -> Result<Self, ReflectError> {
1934 let frame = match self.pop_inner()? {
1935 Some(frame) => frame,
1936 None => {
1937 return Err(ReflectError::InvariantViolation {
1938 invariant: "No frame to pop — it was time to call build()",
1939 });
1940 }
1941 };
1942
1943 self.track(frame);
1944 Ok(self)
1945 }
1946
1947 fn pop_inner(&mut self) -> Result<Option<Frame>, ReflectError> {
1948 let mut frame = match self.frames.pop() {
1949 Some(f) => f,
1950 None => return Ok(None),
1951 };
1952 #[cfg(feature = "log")]
1953 let frame_shape = frame.shape;
1954
1955 let init = frame.is_fully_initialized();
1956 trace!(
1957 "[{}] {} popped, {} initialized",
1958 self.frames.len(),
1959 frame_shape.blue(),
1960 if init {
1961 "✅ fully".style(owo_colors::Style::new().green())
1962 } else {
1963 "🚧 partially".style(owo_colors::Style::new().red())
1964 }
1965 );
1966 if init {
1967 if let Some(parent) = self.frames.last_mut() {
1968 if let Some(index) = frame.field_index_in_parent {
1969 parent.istate.fields.set(index);
1970 }
1971 }
1972 }
1973
1974 match frame.istate.mode {
1976 FrameMode::ListElement => {
1978 if frame.is_fully_initialized() {
1979 #[cfg(feature = "log")]
1981 let frame_len = self.frames.len();
1982
1983 let parent_frame = self.frames.last_mut().unwrap();
1985 let parent_shape = parent_frame.shape;
1986
1987 match parent_shape.def {
1988 Def::List(list_def) => {
1990 let list_vtable = list_def.vtable;
1991 trace!(
1992 "[{}] Pushing element to list {}",
1993 frame_len,
1994 parent_shape.blue()
1995 );
1996 unsafe {
1997 (list_vtable.push)(
1998 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1999 PtrMut::new(frame.data.as_mut_byte_ptr()),
2000 );
2001 self.mark_moved_out_of(&mut frame);
2002 }
2003 }
2004
2005 Def::Struct(sd)
2007 if sd.kind == facet_core::StructKind::Tuple && sd.fields.is_empty() =>
2008 {
2009 trace!(
2010 "[{}] Handling empty tuple struct unit type {}",
2011 frame_len,
2012 parent_shape.blue()
2013 );
2014 unsafe {
2016 parent_frame.mark_fully_initialized();
2017 }
2018 unsafe { self.mark_moved_out_of(&mut frame) };
2020 }
2021 Def::Scalar(s) if matches!(s.affinity, ScalarAffinity::Empty(_)) => {
2022 trace!(
2023 "[{}] Handling scalar empty unit type {}",
2024 frame_len,
2025 parent_shape.blue()
2026 );
2027 unsafe {
2029 parent_frame.mark_fully_initialized();
2030 self.mark_moved_out_of(&mut frame);
2031 }
2032 }
2033
2034 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
2036 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2038 let field_index = previous_index - 1; if field_index >= sd.fields.len() {
2041 panic!(
2042 "Field index {} out of bounds for tuple struct {} with {} fields",
2043 field_index,
2044 parent_shape,
2045 sd.fields.len()
2046 );
2047 }
2048
2049 let field = &sd.fields[field_index];
2050 trace!(
2051 "[{}] Setting tuple struct field {} ({}) of {}",
2052 frame_len,
2053 field_index.to_string().yellow(),
2054 field.name.bright_blue(),
2055 parent_shape.blue()
2056 );
2057
2058 unsafe {
2059 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2061 field_ptr
2062 .copy_from(
2063 PtrConst::new(frame.data.as_byte_ptr()),
2064 field.shape(),
2065 )
2066 .map_err(|_| ReflectError::Unsized {
2067 shape: field.shape(),
2068 })?; parent_frame.istate.fields.set(field_index);
2072
2073 self.mark_moved_out_of(&mut frame);
2075 }
2076 }
2077
2078 Def::Enum(_) => {
2080 let variant =
2082 parent_frame.istate.variant.as_ref().unwrap_or_else(|| {
2083 panic!(
2084 "Popping element for enum {} but no variant was selected",
2085 parent_shape
2086 )
2087 });
2088
2089 if variant.data.kind != facet_core::StructKind::Tuple {
2090 panic!(
2091 "Popping element for enum {}, but selected variant '{}' is not a tuple variant",
2092 parent_shape, variant.name
2093 );
2094 }
2095
2096 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2098 let field_index = previous_index - 1; if field_index >= variant.data.fields.len() {
2101 panic!(
2102 "Field index {} out of bounds for tuple enum variant '{}' of {} with {} fields",
2103 field_index,
2104 variant.name,
2105 parent_shape,
2106 variant.data.fields.len()
2107 );
2108 }
2109
2110 let field = &variant.data.fields[field_index];
2111 trace!(
2112 "[{}] Setting tuple enum variant field {} ({}) of variant '{}' in {}",
2113 frame_len,
2114 field_index.to_string().yellow(),
2115 field.name.bright_blue(),
2116 variant.name.yellow(),
2117 parent_shape.blue()
2118 );
2119
2120 unsafe {
2121 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2123 field_ptr
2124 .copy_from(
2125 PtrConst::new(frame.data.as_byte_ptr()),
2126 field.shape(),
2127 )
2128 .map_err(|_| ReflectError::Unsized {
2129 shape: field.shape(),
2130 })?; parent_frame.istate.fields.set(field_index);
2134
2135 self.mark_moved_out_of(&mut frame);
2137 }
2138 }
2139
2140 _ => {
2142 panic!(
2143 "FrameMode::ListElement pop expected parent to be List, Tuple Struct, or Tuple Enum Variant, but got {}",
2144 parent_shape
2145 );
2146 }
2147 }
2148 } else {
2149 trace!(
2151 "Popping uninitialized ListElement frame ({}), potential leak if allocated resources are not managed",
2152 frame.shape.yellow()
2153 );
2154 }
2155 }
2156
2157 FrameMode::MapValue {
2159 index: key_frame_index,
2160 } if frame.is_fully_initialized() => {
2161 let mut key_frame = self.frames.remove(key_frame_index);
2165
2166 if !key_frame.istate.fields.is_any_set() {
2168 panic!("key is not initialized when popping value frame");
2169 }
2170
2171 #[cfg(feature = "log")]
2173 let frame_len = self.frames.len();
2174 let parent_frame = self.frames.last_mut().unwrap();
2175 let parent_shape = parent_frame.shape;
2176
2177 match parent_shape.def {
2179 Def::Map(_) => {
2180 if let Def::Map(map_def) = parent_shape.def {
2182 trace!(
2183 "[{}] Inserting key-value pair into map {}",
2184 frame_len,
2185 parent_shape.blue()
2186 );
2187 unsafe {
2188 (map_def.vtable.insert_fn)(
2190 parent_frame.data.assume_init(),
2191 key_frame.data.assume_init(),
2192 PtrMut::new(frame.data.as_mut_byte_ptr()),
2193 );
2194 self.mark_moved_out_of(&mut key_frame);
2195 self.mark_moved_out_of(&mut frame);
2196 }
2197 } else {
2198 panic!("parent frame is not a map type");
2199 }
2200 }
2201 _ => {
2202 panic!("Expected map or hash map, got {}", frame.shape);
2203 }
2204 }
2205 }
2206
2207 FrameMode::OptionSome => {
2209 if frame.is_fully_initialized() {
2210 trace!("Popping OptionSome (fully init'd)");
2211
2212 #[cfg(feature = "log")]
2214 let frames_len = self.frames.len();
2215 let parent_frame = self.frames.last_mut().unwrap();
2216 let parent_shape = parent_frame.shape;
2217
2218 match parent_shape.def {
2220 Def::Option(option_def) => {
2221 trace!(
2222 "[{}] Setting Some value in option {}",
2223 frames_len,
2224 parent_shape.blue()
2225 );
2226 unsafe {
2227 (option_def.vtable.init_some_fn)(
2229 parent_frame.data,
2230 PtrConst::new(frame.data.as_byte_ptr()),
2231 );
2232 trace!("Marking parent frame as fully initialized");
2233 parent_frame.mark_fully_initialized();
2234
2235 self.mark_moved_out_of(&mut frame);
2236 }
2237 }
2238 _ => {
2239 panic!(
2240 "Expected parent frame to be an option type, got {}",
2241 frame.shape
2242 );
2243 }
2244 }
2245 } else {
2246 trace!("Popping OptionSome (not fully init'd)");
2247 }
2248 }
2249
2250 FrameMode::MapKey => {}
2253
2254 FrameMode::Field => {}
2256
2257 _ => {}
2259 }
2260
2261 Ok(Some(frame))
2262 }
2263
2264 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
2268 match frame.shape.def {
2269 Def::Struct(sd) => {
2270 for f in sd.fields {
2271 let id = ValueId {
2272 shape: f.shape(),
2273 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
2274 };
2275 if let Some(istate) = self.istates.remove(&id) {
2276 let frame = Frame::recompose(id, istate);
2277 self.evict_tree(frame);
2278 } else {
2279 trace!("No istate found for field {}", f.name);
2280 }
2281 }
2282 }
2283 Def::Enum(_ed) => {
2284 if let Some(variant) = &frame.istate.variant {
2286 trace!(
2287 "Evicting enum {} variant '{}' fields",
2288 frame.shape.blue(),
2289 variant.name.yellow()
2290 );
2291 for field in variant.data.fields {
2293 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2295 let field_shape = field.shape();
2296 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2297
2298 if let Some(field_istate) = self.istates.remove(&field_id) {
2300 trace!(
2301 "Evicting field '{}' (shape {}) of enum variant '{}'",
2302 field.name.bright_blue(),
2303 field_shape.green(),
2304 variant.name.yellow()
2305 );
2306 let field_frame = Frame::recompose(field_id, field_istate);
2308 self.evict_tree(field_frame);
2310 } else {
2311 trace!(
2312 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
2313 field.name.red(),
2314 field_shape.red(),
2315 variant.name.yellow()
2316 );
2317 }
2318 }
2319 } else {
2320 trace!(
2322 "Enum {} has no variant selected, no fields to evict.",
2323 frame.shape.blue()
2324 );
2325 }
2326 }
2327 _ => {}
2328 }
2329 frame
2330 }
2331
2332 #[allow(rustdoc::broken_intra_doc_links)]
2333 pub fn path(&self) -> String {
2336 let mut path = String::from("$");
2337
2338 for (i, frame) in self.frames.iter().enumerate() {
2339 if i == 0 {
2341 continue;
2342 }
2343
2344 match frame.istate.mode {
2345 FrameMode::ListElement => {
2346 if let Some(index) = frame.istate.list_index {
2348 path.push_str(&format!("[{}]", index));
2349 } else {
2350 path.push_str("[?]");
2351 }
2352 }
2353 FrameMode::MapKey => {
2354 path.push_str(".key");
2355 }
2356 FrameMode::MapValue { index: _ } => {
2357 path.push_str(".value");
2358 }
2359 FrameMode::OptionSome => {
2360 path.push_str(".some");
2361 }
2362 FrameMode::OptionNone => {
2363 path.push_str(".none");
2364 }
2365 FrameMode::Root => {
2366 }
2368 FrameMode::Field => {
2369 if let Some(index) = frame.field_index_in_parent {
2371 if let Some(parent) = self.frames.get(i - 1) {
2373 if let Def::Struct(sd) = parent.shape.def {
2374 if index < sd.fields.len() {
2375 let field_name = sd.fields[index].name;
2376 path.push('.');
2377 path.push_str(field_name);
2378 }
2379 } else if let Def::Enum(_) = parent.shape.def {
2380 if let Some(variant) = &parent.istate.variant {
2381 if index < variant.data.fields.len() {
2382 let field_name = variant.data.fields[index].name;
2383 path.push('.');
2384 path.push_str(field_name);
2385 }
2386 }
2387 }
2388 }
2389 }
2390 }
2391 }
2392 }
2393
2394 path
2395 }
2396
2397 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
2399 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
2400 shape: <()>::SHAPE,
2401 operation: "tried to check if field is set, but there was no frame",
2402 })?;
2403
2404 match frame.shape.def {
2405 Def::Struct(ref sd) => {
2406 if index >= sd.fields.len() {
2407 return Err(ReflectError::FieldError {
2408 shape: frame.shape,
2409 field_error: FieldError::NoSuchField,
2410 });
2411 }
2412 Ok(frame.istate.fields.has(index))
2413 }
2414 Def::Enum(_) => {
2415 let variant = frame.istate.variant.as_ref().ok_or(
2416 ReflectError::OperationFailed {
2417 shape: frame.shape,
2418 operation: "tried to check if field is set, but no variant was selected",
2419 },
2420 )?;
2421 if index >= variant.data.fields.len() {
2422 return Err(ReflectError::FieldError {
2423 shape: frame.shape,
2424 field_error: FieldError::NoSuchField,
2425 });
2426 }
2427 Ok(frame.istate.fields.has(index))
2428 }
2429 _ => Err(ReflectError::WasNotA {
2430 expected: "struct or enum",
2431 actual: frame.shape,
2432 }),
2433 }
2434 }
2435}
2436
2437impl Drop for Wip<'_> {
2438 fn drop(&mut self) {
2439 trace!("🧹🧹🧹 WIP is dropping");
2440
2441 while let Some(frame) = self.frames.pop() {
2442 self.track(frame);
2443 }
2444
2445 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
2446 trace!("No root found, we probably built already");
2447 return;
2448 };
2449
2450 let root_id = *root_id;
2451 let root_istate = self.istates.remove(&root_id).unwrap();
2452 let root = Frame::recompose(root_id, root_istate);
2453 let mut to_clean = vec![root];
2454
2455 let mut _root_guard: Option<Guard> = None;
2456
2457 while let Some(mut frame) = to_clean.pop() {
2458 trace!(
2459 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
2460 frame.shape.blue(),
2461 frame.data.as_byte_ptr(),
2462 frame.istate.flags.bright_magenta(),
2463 frame.istate.mode.yellow(),
2464 if frame.is_fully_initialized() {
2465 "✅"
2466 } else {
2467 "❌"
2468 }
2469 );
2470
2471 if frame.istate.flags.contains(FrameFlags::MOVED) {
2472 trace!(
2473 "{}",
2474 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
2475 );
2476 continue;
2477 }
2478
2479 match frame.shape.def {
2480 Def::Struct(sd) => {
2481 if frame.is_fully_initialized() {
2482 trace!(
2483 "Dropping fully initialized struct: {} at {:p}",
2484 frame.shape.green(),
2485 frame.data.as_byte_ptr()
2486 );
2487 let frame = self.evict_tree(frame);
2488 unsafe { frame.drop_and_dealloc_if_needed() };
2489 } else {
2490 let num_fields = sd.fields.len();
2491 trace!(
2492 "De-initializing struct {} at {:p} field-by-field ({} fields)",
2493 frame.shape.yellow(),
2494 frame.data.as_byte_ptr(),
2495 num_fields.to_string().bright_cyan()
2496 );
2497 for i in 0..num_fields {
2498 if frame.istate.fields.has(i) {
2499 let field = sd.fields[i];
2500 let field_shape = field.shape();
2501 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
2502 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2503 trace!(
2504 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
2505 i.to_string().bright_cyan(),
2506 field.name.bright_blue(),
2507 frame.shape.blue(),
2508 field_shape.green(),
2509 field_ptr.as_byte_ptr()
2510 );
2511 let istate = self.istates.remove(&field_id).unwrap();
2512 let field_frame = Frame::recompose(field_id, istate);
2513 to_clean.push(field_frame);
2514 } else {
2515 trace!(
2516 "Field #{} '{}' of {} was NOT initialized, skipping",
2517 i.to_string().bright_cyan(),
2518 sd.fields[i].name.bright_red(),
2519 frame.shape.red()
2520 );
2521 }
2522 }
2523
2524 if frame.istate.mode == FrameMode::Root {
2526 if let Ok(layout) = frame.shape.layout.sized_layout() {
2527 _root_guard = Some(Guard {
2528 ptr: frame.data.as_mut_byte_ptr(),
2529 layout,
2530 });
2531 }
2532 }
2533 }
2534 }
2535 Def::Enum(_ed) => {
2536 trace!(
2537 "{}",
2538 format_args!(
2539 "TODO: handle enum deallocation for {} at {:p}",
2540 frame.shape.yellow(),
2541 frame.data.as_byte_ptr()
2542 )
2543 .magenta()
2544 );
2545
2546 if frame.istate.mode == FrameMode::Root {
2548 if let Ok(layout) = frame.shape.layout.sized_layout() {
2549 _root_guard = Some(Guard {
2550 ptr: frame.data.as_mut_byte_ptr(),
2551 layout,
2552 });
2553 }
2554 }
2555 }
2556 Def::Array(_)
2557 | Def::Slice(_)
2558 | Def::List(_)
2559 | Def::Map(_)
2560 | Def::SmartPointer(_)
2561 | Def::Scalar(_)
2562 | Def::FunctionPointer(_)
2563 | Def::Option(_) => {
2564 trace!(
2565 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
2566 frame.shape.cyan(),
2567 frame.shape.def,
2568 frame.istate.mode.yellow(),
2569 frame.data.as_byte_ptr(),
2570 );
2571
2572 if frame.is_fully_initialized() {
2573 unsafe { frame.drop_and_dealloc_if_needed() }
2574 } else {
2575 frame.dealloc_if_needed();
2576 }
2577 }
2578 _ => {}
2579 }
2580 }
2581
2582 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
2584 for frame_id in all_ids.drain(..) {
2585 let frame_istate = self.istates.remove(&frame_id).unwrap();
2586
2587 trace!(
2588 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
2589 frame_id.shape.cyan(),
2590 frame_id.ptr,
2591 frame_istate.mode.yellow()
2592 );
2593 let mut frame = Frame::recompose(frame_id, frame_istate);
2594
2595 if frame.is_fully_initialized() {
2596 trace!("It's fully initialized, we can drop it");
2597 unsafe { frame.drop_and_dealloc_if_needed() };
2598 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
2599 trace!("Not initialized but allocated, let's free it");
2600 frame.dealloc_if_needed();
2601 }
2602 }
2603 }
2604}