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 DisplayToDebug<T>(T);
105
106impl<T> fmt::Debug for DisplayToDebug<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", &DisplayToDebug(&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.iter().position(|f| f.name == name)
814 }
815
816 let frame = self.frames.last()?;
817 match frame.shape.def {
818 Def::Struct(def) => find_field_index(def.fields, name),
819 Def::Enum(_) => {
820 let variant = frame.istate.variant.as_ref()?;
821 find_field_index(variant.data.fields, name)
822 }
823 _ => None,
824 }
825 }
826
827 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
839 let frame = self.frames.last().unwrap();
840 let shape = frame.shape;
841
842 if let Def::Enum(_) = shape.def {
844 if frame.istate.variant.is_none() {
845 return Err(ReflectError::OperationFailed {
846 shape,
847 operation: "tried to access a field by name but no variant was selected",
848 });
849 }
850 }
851
852 let index = self.field_index(name).ok_or(ReflectError::FieldError {
853 shape,
854 field_error: FieldError::NoSuchField,
855 })?;
856
857 self.field(index)
858 }
859
860 pub fn put<T: Facet<'facet_lifetime>>(
871 self,
872 t: T,
873 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
874 let shape = T::SHAPE;
875 let ptr_const = PtrConst::new(&t as *const T as *const u8);
876 let res = self.put_shape(ptr_const, shape);
877 core::mem::forget(t); res
879 }
880
881 pub fn try_put<T: Facet<'facet_lifetime>>(
892 self,
893 t: T,
894 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
895 let shape = T::SHAPE;
896 let ptr_const = PtrConst::new(&t as *const T as *const u8);
897 let res = self.put_shape(ptr_const, shape);
898 core::mem::forget(t); res
900 }
901
902 pub fn put_shape(
904 mut self,
905 src: PtrConst<'_>,
906 src_shape: &'static Shape,
907 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
908 let Some(frame) = self.frames.last_mut() else {
909 return Err(ReflectError::OperationFailed {
910 shape: src_shape,
911 operation: "tried to put a value but there was no frame to put into",
912 });
913 };
914
915 if frame.shape != src_shape {
917 trace!(
918 "Trying to put a {} into a {}",
919 src_shape.yellow(),
920 frame.shape.magenta()
921 );
922
923 if let Some(inner_fn) = frame.shape.inner {
925 let inner_shape = inner_fn();
927
928 if src_shape == inner_shape {
930 if let Some(try_from_fn) = frame.shape.vtable.try_from {
932 match unsafe { (try_from_fn)(src, src_shape, frame.data) } {
933 Ok(_) => {
934 unsafe {
935 frame.mark_fully_initialized();
936 }
937
938 let shape = frame.shape;
939 let index = frame.field_index_in_parent;
940
941 self.mark_field_as_initialized(shape, index)?;
943
944 debug!(
945 "[{}] Just put a {} value into transparent type {}",
946 self.frames.len(),
947 src_shape.green(),
948 shape.blue()
949 );
950
951 return Ok(self);
952 }
953 Err(e) => {
954 return Err(ReflectError::TryFromError {
955 inner: e,
956 src_shape,
957 dst_shape: frame.shape,
958 });
959 }
960 }
961 } else {
962 debug!(
964 "No try_from_inner function for transparent type, falling back to TryFrom"
965 );
966 }
967 }
968 }
969
970 if let Some(try_from) = frame.shape.vtable.try_from {
972 match unsafe { try_from(src, src_shape, frame.data) } {
973 Ok(_) => {
974 unsafe {
975 frame.mark_fully_initialized();
976 }
977
978 let shape = frame.shape;
979 let index = frame.field_index_in_parent;
980
981 self.mark_field_as_initialized(shape, index)?;
983
984 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
985
986 return Ok(self);
987 }
988 Err(e) => {
989 return Err(ReflectError::TryFromError {
990 inner: e,
991 src_shape,
992 dst_shape: frame.shape,
993 });
994 }
995 }
996 }
997
998 if let Def::Option(od) = frame.shape.def {
1001 if od.t() == src_shape {
1003 debug!("Putting into an Option<T>!");
1004 if frame.istate.fields.is_any_set() {
1005 let data = unsafe { frame.data.assume_init() };
1006 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
1007 } else {
1008 let data = frame.data;
1009 unsafe { (od.vtable.init_some_fn)(data, src) };
1010 }
1011 unsafe {
1012 frame.mark_fully_initialized();
1013 }
1014
1015 let shape = frame.shape;
1016 let index = frame.field_index_in_parent;
1017
1018 self.mark_field_as_initialized(shape, index)?;
1020
1021 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1022
1023 return Ok(self);
1024 }
1025 }
1026
1027 if let Def::Struct(sd) = frame.shape.def {
1031 for (i, field) in sd.fields.iter().enumerate() {
1033 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1034 debug!(
1035 "Found uninitialized field {} with matching type {}",
1036 i.to_string().blue(),
1037 src_shape.green()
1038 );
1039
1040 unsafe {
1042 let field_data = frame.data.field_uninit_at(field.offset);
1043 field_data.copy_from(src, field.shape()).map_err(|_| {
1044 ReflectError::Unsized {
1045 shape: field.shape(),
1046 }
1047 })?;
1048 frame.istate.fields.set(i);
1049 }
1050
1051 let shape = frame.shape;
1052 let index = frame.field_index_in_parent;
1053
1054 if frame.is_fully_initialized() {
1056 self.mark_field_as_initialized(shape, index)?;
1057 }
1058
1059 debug!(
1060 "[{}] Put a {} value into field {} of {}",
1061 self.frames.len(),
1062 src_shape.green(),
1063 i.to_string().blue(),
1064 shape.green()
1065 );
1066
1067 return Ok(self);
1068 }
1069 }
1070 }
1071
1072 if let Def::Enum(_) = frame.shape.def {
1075 if let Some(variant) = &frame.istate.variant {
1077 for (i, field) in variant.data.fields.iter().enumerate() {
1079 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1080 debug!(
1081 "Found uninitialized field {} in enum variant '{}' with matching type {}",
1082 i.to_string().blue(),
1083 variant.name.bright_yellow(),
1084 src_shape.green()
1085 );
1086
1087 unsafe {
1089 let field_data = frame.data.field_uninit_at(field.offset);
1090 field_data.copy_from(src, field.shape()).map_err(|_| {
1091 ReflectError::Unsized {
1092 shape: field.shape(),
1093 }
1094 })?;
1095 frame.istate.fields.set(i);
1096 }
1097
1098 let shape = frame.shape;
1099 let index = frame.field_index_in_parent;
1100
1101 #[allow(unused)]
1102 let variant_name = variant.name;
1103
1104 if frame.is_fully_initialized() {
1106 self.mark_field_as_initialized(shape, index)?;
1107 }
1108
1109 debug!(
1110 "[{}] Put a {} value into field {} of variant '{}' in enum {}",
1111 self.frames.len(),
1112 src_shape.green(),
1113 i.to_string().blue(),
1114 variant_name.bright_yellow(),
1115 shape.green()
1116 );
1117
1118 return Ok(self);
1119 }
1120 }
1121 }
1122 }
1123
1124 return Err(ReflectError::WrongShape {
1125 expected: frame.shape,
1126 actual: src_shape,
1127 });
1128 }
1129
1130 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
1132 debug!("De-initializing partially initialized {:?}", frame.yellow());
1133
1134 match frame.shape.def {
1135 Def::Struct(sd) => {
1136 for (i, field) in sd.fields.iter().enumerate() {
1137 if frame.istate.fields.has(i) {
1138 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1139 unsafe {
1140 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
1141 drop_fn(PtrMut::new(field_ptr));
1142 }
1143 }
1144 }
1145 }
1146 }
1147 Def::Enum(_) => {
1148 if let Some(variant) = &frame.istate.variant {
1149 for (i, field) in variant.data.fields.iter().enumerate() {
1150 if frame.istate.fields.has(i) {
1151 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1152 unsafe {
1153 let field_ptr =
1154 frame.data.as_mut_byte_ptr().add(field.offset);
1155 drop_fn(PtrMut::new(field_ptr));
1156 }
1157 }
1158 }
1159 }
1160 }
1161 }
1162 _ => {
1163 if frame.istate.fields.is_any_set() {
1165 debug!("Scalar type was set...");
1166 if let Some(drop_fn) = frame.shape.vtable.drop_in_place {
1167 debug!("And it has a drop fn, dropping now!");
1168 unsafe {
1169 drop_fn(frame.data.assume_init());
1170 }
1171 }
1172 }
1173 }
1174 }
1175
1176 frame.istate.variant = None;
1178 ISet::clear(&mut frame.istate.fields);
1179 }
1180
1181 unsafe {
1182 frame
1184 .data
1185 .copy_from(src, frame.shape)
1186 .map_err(|_| ReflectError::Unsized { shape: frame.shape })?;
1187 frame.mark_fully_initialized();
1188 }
1189
1190 let shape = frame.shape;
1191 let index = frame.field_index_in_parent;
1192
1193 self.mark_field_as_initialized(shape, index)?;
1195
1196 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1197
1198 Ok(self)
1199 }
1200
1201 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
1203 let Some(frame) = self.frames.last_mut() else {
1204 return Err(ReflectError::OperationFailed {
1205 shape: <()>::SHAPE,
1206 operation: "tried to parse value but there was no frame",
1207 });
1208 };
1209
1210 let shape = frame.shape;
1211 let index = frame.field_index_in_parent;
1212
1213 let Some(parse_fn) = frame.shape.vtable.parse else {
1214 return Err(ReflectError::OperationFailed {
1215 shape: frame.shape,
1216 operation: "type does not implement Parse",
1217 });
1218 };
1219 match unsafe { (parse_fn)(s, frame.data) } {
1220 Ok(_res) => {
1221 unsafe {
1222 frame.mark_fully_initialized();
1223 }
1224
1225 self.mark_field_as_initialized(shape, index)?;
1227
1228 Ok(self)
1229 }
1230 Err(_) => Err(ReflectError::OperationFailed {
1231 shape,
1232 operation: "parsing",
1233 }),
1234 }
1235 }
1236
1237 pub fn put_from_fn(mut self, default_in_place: DefaultInPlaceFn) -> Result<Self, ReflectError> {
1239 let Some(frame) = self.frames.last_mut() else {
1240 return Err(ReflectError::OperationFailed {
1241 shape: <()>::SHAPE,
1242 operation: "tried to put value from fn but there was no frame",
1243 });
1244 };
1245
1246 unsafe {
1247 default_in_place(frame.data);
1248 frame.mark_fully_initialized();
1249 }
1250
1251 let shape = frame.shape;
1252 let index = frame.field_index_in_parent;
1253
1254 self.mark_field_as_initialized(shape, index)?;
1256
1257 Ok(self)
1258 }
1259
1260 pub fn put_default(self) -> Result<Self, ReflectError> {
1262 let Some(frame) = self.frames.last() else {
1263 return Err(ReflectError::OperationFailed {
1264 shape: <()>::SHAPE,
1265 operation: "tried to put default value but there was no frame",
1266 });
1267 };
1268
1269 let vtable = frame.shape.vtable;
1270 let Some(default_in_place) = vtable.default_in_place else {
1271 return Err(ReflectError::OperationFailed {
1272 shape: frame.shape,
1273 operation: "type does not implement Default",
1274 });
1275 };
1276
1277 self.put_from_fn(default_in_place)
1278 }
1279
1280 fn mark_field_as_initialized(
1282 &mut self,
1283 shape: &'static Shape,
1284 index: Option<usize>,
1285 ) -> Result<(), ReflectError> {
1286 if let Some(index) = index {
1287 let parent_index = self.frames.len().saturating_sub(2);
1288 #[cfg(feature = "log")]
1289 let num_frames = self.frames.len();
1290 let Some(parent) = self.frames.get_mut(parent_index) else {
1291 return Err(ReflectError::OperationFailed {
1292 shape,
1293 operation: "was supposed to mark a field as initialized, but there was no parent frame",
1294 });
1295 };
1296 #[cfg(feature = "log")]
1297 let parent_shape = parent.shape;
1298 trace!(
1299 "[{}] {}.{} initialized with {}",
1300 num_frames,
1301 parent_shape.blue(),
1302 index.yellow(),
1303 shape.green()
1304 );
1305
1306 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
1307 return Err(ReflectError::OperationFailed {
1308 shape,
1309 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
1310 });
1311 }
1312
1313 if parent.istate.fields.has(index) {
1314 return Err(ReflectError::OperationFailed {
1315 shape,
1316 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
1317 });
1318 }
1319
1320 parent.istate.fields.set(index);
1321 }
1322 Ok(())
1323 }
1324
1325 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
1327 let frame = self.frames.last().unwrap();
1328 let shape = frame.shape;
1329
1330 match shape.def {
1331 Def::List(list_def) => Ok(list_def.t()),
1332 _ => Err(ReflectError::WasNotA {
1333 expected: "list or array",
1334 actual: shape,
1335 }),
1336 }
1337 }
1338
1339 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
1341 let frame = self.frames.last().unwrap();
1342 let shape = frame.shape;
1343
1344 match shape.def {
1345 Def::Map(map_def) => Ok(map_def.k),
1346 _ => Err(ReflectError::WasNotA {
1347 expected: "map",
1348 actual: shape,
1349 }),
1350 }
1351 }
1352
1353 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
1355 let Some(frame) = self.frames.last_mut() else {
1356 return Err(ReflectError::OperationFailed {
1357 shape: <()>::SHAPE,
1358 operation: "tried to create empty list but there was no frame",
1359 });
1360 };
1361
1362 if !matches!(frame.shape.def, Def::List(_)) {
1363 return Err(ReflectError::WasNotA {
1364 expected: "list or array",
1365 actual: frame.shape,
1366 });
1367 }
1368
1369 let vtable = frame.shape.vtable;
1370
1371 let Some(default_in_place) = vtable.default_in_place else {
1373 return Err(ReflectError::OperationFailed {
1374 shape: frame.shape,
1375 operation: "list type does not implement Default",
1376 });
1377 };
1378
1379 unsafe {
1380 default_in_place(frame.data);
1381 frame.mark_fully_initialized();
1382 }
1383
1384 let shape = frame.shape;
1385 let index = frame.field_index_in_parent;
1386
1387 self.mark_field_as_initialized(shape, index)?;
1389
1390 Ok(self)
1391 }
1392
1393 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1395 let Some(frame) = self.frames.last_mut() else {
1396 return Err(ReflectError::OperationFailed {
1397 shape: <()>::SHAPE,
1398 operation: "tried to create empty map but there was no frame",
1399 });
1400 };
1401
1402 if !matches!(frame.shape.def, Def::Map(_)) {
1403 return Err(ReflectError::WasNotA {
1404 expected: "map or hash map",
1405 actual: frame.shape,
1406 });
1407 }
1408
1409 let vtable = frame.shape.vtable;
1410
1411 let Some(default_in_place) = vtable.default_in_place else {
1413 return Err(ReflectError::OperationFailed {
1414 shape: frame.shape,
1415 operation: "map type does not implement Default",
1416 });
1417 };
1418
1419 unsafe {
1420 default_in_place(frame.data);
1421 frame.mark_fully_initialized();
1422 }
1423
1424 let shape = frame.shape;
1425 let index = frame.field_index_in_parent;
1426
1427 self.mark_field_as_initialized(shape, index)?;
1429
1430 Ok(self)
1431 }
1432
1433 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1438 let Some(frame) = self.frames.last_mut() else {
1439 return Err(ReflectError::OperationFailed {
1440 shape: <()>::SHAPE,
1441 operation: "tried to begin pushback but there was no frame",
1442 });
1443 };
1444
1445 let is_list = matches!(frame.shape.def, Def::List(_));
1446 let is_tuple_struct_or_variant = match frame.shape.def {
1447 Def::Struct(sd) => sd.kind == facet_core::StructKind::Tuple,
1448 Def::Enum(_) => {
1449 if let Some(variant) = &frame.istate.variant {
1451 variant.data.kind == facet_core::StructKind::Tuple
1452 } else {
1453 false }
1462 }
1463 _ => false,
1464 };
1465
1466 if !is_list && !is_tuple_struct_or_variant {
1467 return Err(ReflectError::WasNotA {
1468 expected: "list, array, or tuple-like struct/enum variant",
1469 actual: frame.shape,
1470 });
1471 }
1472
1473 if is_list {
1475 let vtable = frame.shape.vtable;
1476 if !frame.istate.fields.has(0) {
1478 let Some(default_in_place) = vtable.default_in_place else {
1479 return Err(ReflectError::OperationFailed {
1480 shape: frame.shape,
1481 operation: "list type does not implement Default, cannot begin pushback",
1482 });
1483 };
1484
1485 unsafe {
1486 default_in_place(frame.data);
1487 frame.istate.fields.set(0);
1489 }
1490 }
1491 }
1492 Ok(self)
1495 }
1496
1497 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1499 let Some(frame) = self.frames.last_mut() else {
1500 return Err(ReflectError::OperationFailed {
1501 shape: <()>::SHAPE,
1502 operation: "tried to begin map insertion but there was no frame",
1503 });
1504 };
1505
1506 if !matches!(frame.shape.def, Def::Map(_)) {
1507 return Err(ReflectError::WasNotA {
1508 expected: "map or hash map",
1509 actual: frame.shape,
1510 });
1511 }
1512
1513 let vtable = frame.shape.vtable;
1514
1515 if !frame.istate.fields.has(0) {
1517 let Some(default_in_place) = vtable.default_in_place else {
1518 return Err(ReflectError::OperationFailed {
1519 shape: frame.shape,
1520 operation: "map type does not implement Default",
1521 });
1522 };
1523
1524 unsafe {
1525 default_in_place(frame.data);
1526 frame.istate.fields.set(0);
1527 }
1528 }
1529
1530 Ok(self)
1531 }
1532
1533 pub fn push(mut self) -> Result<Self, ReflectError> {
1538 let frame_len = self.frames.len();
1540 let frame = self
1541 .frames
1542 .last_mut()
1543 .ok_or(ReflectError::OperationFailed {
1544 shape: <()>::SHAPE,
1545 operation: "tried to push but there was no frame",
1546 })?;
1547 let seq_shape = frame.shape;
1548
1549 let (element_shape, context_str): (&'static Shape, &'static str) = match seq_shape.def {
1551 Def::List(_) => {
1552 if !frame.istate.fields.has(0) {
1554 return self.begin_pushback()?.push();
1557 }
1558 let shape = self.element_shape()?;
1561 (shape, "list")
1562 }
1563
1564 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
1565 let field_index = {
1567 let next_idx = frame.istate.list_index.unwrap_or(0);
1569 frame.istate.list_index = Some(next_idx + 1);
1570 next_idx
1571 };
1572 if field_index >= sd.fields.len() {
1574 return Err(ReflectError::FieldError {
1575 shape: seq_shape,
1576 field_error: FieldError::NoSuchField, });
1578 }
1579 (sd.fields[field_index].shape(), "tuple struct")
1581 }
1582
1583 Def::Enum(_) => {
1584 let variant =
1586 frame
1587 .istate
1588 .variant
1589 .as_ref()
1590 .ok_or(ReflectError::OperationFailed {
1591 shape: seq_shape,
1592 operation: "tried to push onto enum but no variant was selected",
1593 })?;
1594 if variant.data.kind != facet_core::StructKind::Tuple {
1596 return Err(ReflectError::WasNotA {
1597 expected: "tuple-like enum variant",
1598 actual: seq_shape, });
1600 }
1601 let field_index = {
1603 let next_idx = frame.istate.list_index.unwrap_or(0);
1605 frame.istate.list_index = Some(next_idx + 1);
1606 next_idx
1607 };
1608 if field_index >= variant.data.fields.len() {
1610 return Err(ReflectError::FieldError {
1611 shape: seq_shape, field_error: FieldError::NoSuchField,
1613 });
1614 }
1615 (
1617 variant.data.fields[field_index].shape(),
1618 "tuple enum variant",
1619 )
1620 }
1621
1622 _ => {
1623 return Err(ReflectError::WasNotA {
1625 expected: "list, array, tuple struct, or tuple enum variant",
1626 actual: seq_shape,
1627 });
1628 }
1629 };
1630
1631 let element_data = element_shape
1633 .allocate()
1634 .map_err(|_| ReflectError::Unsized {
1635 shape: element_shape,
1636 })?;
1637
1638 let element_frame = Frame {
1640 data: element_data,
1641 shape: element_shape,
1642 field_index_in_parent: None, istate: IState::new(
1644 frame_len, FrameMode::ListElement, FrameFlags::ALLOCATED,
1647 ),
1648 };
1649
1650 trace!(
1651 "[{}] Pushing element of type {} to {} {}",
1652 frame_len,
1653 element_shape.green(),
1654 context_str, seq_shape.blue(),
1656 );
1657 let _ = context_str;
1658
1659 self.frames.push(element_frame);
1660 Ok(self)
1661 }
1662
1663 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1665 let frame = self.frames.last().unwrap();
1667 let option_shape = frame.shape;
1668
1669 let Def::Option(option_def) = option_shape.def else {
1671 return Err(ReflectError::WasNotA {
1672 expected: "option",
1673 actual: option_shape,
1674 });
1675 };
1676
1677 let inner_shape = option_def.t();
1679
1680 let inner_data = inner_shape
1682 .allocate()
1683 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1684
1685 let inner_frame = Frame {
1687 data: inner_data,
1688 shape: inner_shape,
1689 field_index_in_parent: None,
1691 istate: IState::new(
1692 self.frames.len(),
1693 FrameMode::OptionSome,
1694 FrameFlags::ALLOCATED,
1696 ),
1697 };
1698
1699 trace!(
1700 "[{}] Pushing option frame for {}",
1701 self.frames.len(),
1702 option_shape.blue(),
1703 );
1704
1705 self.frames.push(inner_frame);
1706 Ok(self)
1707 }
1708
1709 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1719 let Some(frame) = self.frames.last_mut() else {
1721 return Err(ReflectError::OperationFailed {
1722 shape: <()>::SHAPE,
1723 operation: "tried to pop_some_push_none but there was no frame",
1724 });
1725 };
1726
1727 if frame.istate.mode != FrameMode::OptionSome {
1729 return Err(ReflectError::OperationFailed {
1730 shape: frame.shape,
1731 operation: "pop_some_push_none called, but frame was not in Option mode",
1732 });
1733 }
1734
1735 if frame.is_fully_initialized() {
1737 return Err(ReflectError::OperationFailed {
1738 shape: frame.shape,
1739 operation: "option frame already initialized, cannot pop_some_push_none",
1740 });
1741 }
1742
1743 frame.dealloc_if_needed();
1744
1745 let _frame = self.frames.pop().expect("frame already checked");
1747
1748 let parent_frame = self
1750 .frames
1751 .last_mut()
1752 .ok_or(ReflectError::OperationFailed {
1753 shape: <()>::SHAPE,
1754 operation: "tried to pop_some_push_none but there was no parent frame",
1755 })?;
1756
1757 unsafe {
1759 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1760 default_fn(parent_frame.data);
1761 } else {
1762 return Err(ReflectError::OperationFailed {
1763 shape: parent_frame.shape,
1764 operation: "option type does not implement Default",
1765 });
1766 }
1767 parent_frame.mark_fully_initialized();
1768 }
1769
1770 let Def::Option(od) = parent_frame.shape.def else {
1771 return Err(ReflectError::OperationFailed {
1772 shape: parent_frame.shape,
1773 operation: "pop_some_push_none and the parent isn't of type Option???",
1774 });
1775 };
1776
1777 let data = parent_frame.data;
1779
1780 let mut frame = Frame {
1781 data,
1782 shape: od.t(),
1783 field_index_in_parent: Some(0),
1784 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1785 };
1786 unsafe {
1787 frame.mark_fully_initialized();
1788 }
1789
1790 self.frames.push(frame);
1791
1792 Ok(self)
1793 }
1794
1795 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1800 let frame = self.frames.last().unwrap();
1802 let map_shape = frame.shape;
1803
1804 if !matches!(map_shape.def, Def::Map(_)) {
1805 return Err(ReflectError::WasNotA {
1806 expected: "map or hash map",
1807 actual: map_shape,
1808 });
1809 }
1810
1811 if !frame.istate.fields.has(0) {
1813 self = self.begin_map_insert()?;
1814 }
1815
1816 let key_shape = self.key_shape()?;
1818
1819 let key_data = key_shape
1821 .allocate()
1822 .map_err(|_| ReflectError::Unsized { shape: key_shape })?;
1823
1824 let key_frame = Frame {
1826 data: key_data,
1827 shape: key_shape,
1828 field_index_in_parent: None,
1829 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1830 };
1831
1832 trace!(
1833 "[{}] Pushing key of type {} for map {}",
1834 self.frames.len(),
1835 key_shape.green(),
1836 map_shape.blue(),
1837 );
1838
1839 self.frames.push(key_frame);
1840 Ok(self)
1841 }
1842
1843 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1848 trace!("Wants to push map value. Frames = ");
1849 #[cfg(feature = "log")]
1850 for (i, f) in self.frames.iter().enumerate() {
1851 trace!("Frame {}: {:?}", i, f);
1852 }
1853
1854 if self.frames.len() < 2 {
1856 return Err(ReflectError::OperationFailed {
1857 shape: <()>::SHAPE,
1858 operation: "tried to push map value but there was no key frame",
1859 });
1860 }
1861
1862 let key_frame_index = self.frames.len() - 1;
1864 let key_frame = &self.frames[key_frame_index];
1865
1866 match key_frame.istate.mode {
1868 FrameMode::MapKey => {} _ => {
1870 return Err(ReflectError::OperationFailed {
1871 shape: key_frame.shape,
1872 operation: "current frame is not a map key",
1873 });
1874 }
1875 }
1876
1877 if !key_frame.is_fully_initialized() {
1879 return Err(ReflectError::OperationFailed {
1880 shape: key_frame.shape,
1881 operation: "map key is not fully initialized",
1882 });
1883 }
1884
1885 let map_frame_index = self.frames.len() - 2;
1887 let map_frame = &self.frames[map_frame_index];
1888 let map_shape = map_frame.shape;
1889
1890 let Def::Map(map_def) = map_shape.def else {
1891 return Err(ReflectError::WasNotA {
1892 expected: "map",
1893 actual: map_frame.shape,
1894 });
1895 };
1896
1897 let value_shape = map_def.v;
1898
1899 let value_data = value_shape
1901 .allocate()
1902 .map_err(|_| ReflectError::Unsized { shape: value_shape })?;
1903
1904 let value_frame = Frame {
1906 data: value_data,
1907 shape: value_shape,
1908 field_index_in_parent: None,
1909 istate: IState::new(
1910 self.frames.len(),
1911 FrameMode::MapValue {
1912 index: key_frame_index,
1913 },
1914 FrameFlags::ALLOCATED,
1915 ),
1916 };
1917
1918 trace!(
1919 "[{}] Pushing value of type {} for map {} with key type {}",
1920 self.frames.len(),
1921 value_shape.green(),
1922 map_shape.blue(),
1923 key_frame.shape.yellow(),
1924 );
1925
1926 self.frames.push(value_frame);
1927 Ok(self)
1928 }
1929
1930 pub fn pop(mut self) -> Result<Self, ReflectError> {
1932 let frame = match self.pop_inner()? {
1933 Some(frame) => frame,
1934 None => {
1935 return Err(ReflectError::InvariantViolation {
1936 invariant: "No frame to pop — it was time to call build()",
1937 });
1938 }
1939 };
1940
1941 self.track(frame);
1942 Ok(self)
1943 }
1944
1945 fn pop_inner(&mut self) -> Result<Option<Frame>, ReflectError> {
1946 let mut frame = match self.frames.pop() {
1947 Some(f) => f,
1948 None => return Ok(None),
1949 };
1950 #[cfg(feature = "log")]
1951 let frame_shape = frame.shape;
1952
1953 let init = frame.is_fully_initialized();
1954 trace!(
1955 "[{}] {} popped, {} initialized",
1956 self.frames.len(),
1957 frame_shape.blue(),
1958 if init {
1959 "✅ fully".style(owo_colors::Style::new().green())
1960 } else {
1961 "🚧 partially".style(owo_colors::Style::new().red())
1962 }
1963 );
1964 if init {
1965 if let Some(parent) = self.frames.last_mut() {
1966 if let Some(index) = frame.field_index_in_parent {
1967 parent.istate.fields.set(index);
1968 }
1969 }
1970 }
1971
1972 match frame.istate.mode {
1974 FrameMode::ListElement => {
1976 if frame.is_fully_initialized() {
1977 #[cfg(feature = "log")]
1979 let frame_len = self.frames.len();
1980
1981 let parent_frame = self.frames.last_mut().unwrap();
1983 let parent_shape = parent_frame.shape;
1984
1985 match parent_shape.def {
1986 Def::List(list_def) => {
1988 let list_vtable = list_def.vtable;
1989 trace!(
1990 "[{}] Pushing element to list {}",
1991 frame_len,
1992 parent_shape.blue()
1993 );
1994 unsafe {
1995 (list_vtable.push)(
1996 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1997 PtrMut::new(frame.data.as_mut_byte_ptr()),
1998 );
1999 self.mark_moved_out_of(&mut frame);
2000 }
2001 }
2002
2003 Def::Struct(sd)
2005 if sd.kind == facet_core::StructKind::Tuple && sd.fields.is_empty() =>
2006 {
2007 trace!(
2008 "[{}] Handling empty tuple struct unit type {}",
2009 frame_len,
2010 parent_shape.blue()
2011 );
2012 unsafe {
2014 parent_frame.mark_fully_initialized();
2015 }
2016 unsafe { self.mark_moved_out_of(&mut frame) };
2018 }
2019 Def::Scalar(s) if matches!(s.affinity, ScalarAffinity::Empty(_)) => {
2020 trace!(
2021 "[{}] Handling scalar empty unit type {}",
2022 frame_len,
2023 parent_shape.blue()
2024 );
2025 unsafe {
2027 parent_frame.mark_fully_initialized();
2028 self.mark_moved_out_of(&mut frame);
2029 }
2030 }
2031
2032 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
2034 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2036 let field_index = previous_index - 1; if field_index >= sd.fields.len() {
2039 panic!(
2040 "Field index {} out of bounds for tuple struct {} with {} fields",
2041 field_index,
2042 parent_shape,
2043 sd.fields.len()
2044 );
2045 }
2046
2047 let field = &sd.fields[field_index];
2048 trace!(
2049 "[{}] Setting tuple struct field {} ({}) of {}",
2050 frame_len,
2051 field_index.to_string().yellow(),
2052 field.name.bright_blue(),
2053 parent_shape.blue()
2054 );
2055
2056 unsafe {
2057 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2059 field_ptr
2060 .copy_from(
2061 PtrConst::new(frame.data.as_byte_ptr()),
2062 field.shape(),
2063 )
2064 .map_err(|_| ReflectError::Unsized {
2065 shape: field.shape(),
2066 })?; parent_frame.istate.fields.set(field_index);
2070
2071 self.mark_moved_out_of(&mut frame);
2073 }
2074 }
2075
2076 Def::Enum(_) => {
2078 let variant =
2080 parent_frame.istate.variant.as_ref().unwrap_or_else(|| {
2081 panic!(
2082 "Popping element for enum {} but no variant was selected",
2083 parent_shape
2084 )
2085 });
2086
2087 if variant.data.kind != facet_core::StructKind::Tuple {
2088 panic!(
2089 "Popping element for enum {}, but selected variant '{}' is not a tuple variant",
2090 parent_shape, variant.name
2091 );
2092 }
2093
2094 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2096 let field_index = previous_index - 1; if field_index >= variant.data.fields.len() {
2099 panic!(
2100 "Field index {} out of bounds for tuple enum variant '{}' of {} with {} fields",
2101 field_index,
2102 variant.name,
2103 parent_shape,
2104 variant.data.fields.len()
2105 );
2106 }
2107
2108 let field = &variant.data.fields[field_index];
2109 trace!(
2110 "[{}] Setting tuple enum variant field {} ({}) of variant '{}' in {}",
2111 frame_len,
2112 field_index.to_string().yellow(),
2113 field.name.bright_blue(),
2114 variant.name.yellow(),
2115 parent_shape.blue()
2116 );
2117
2118 unsafe {
2119 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2121 field_ptr
2122 .copy_from(
2123 PtrConst::new(frame.data.as_byte_ptr()),
2124 field.shape(),
2125 )
2126 .map_err(|_| ReflectError::Unsized {
2127 shape: field.shape(),
2128 })?; parent_frame.istate.fields.set(field_index);
2132
2133 self.mark_moved_out_of(&mut frame);
2135 }
2136 }
2137
2138 _ => {
2140 panic!(
2141 "FrameMode::ListElement pop expected parent to be List, Tuple Struct, or Tuple Enum Variant, but got {}",
2142 parent_shape
2143 );
2144 }
2145 }
2146 } else {
2147 trace!(
2149 "Popping uninitialized ListElement frame ({}), potential leak if allocated resources are not managed",
2150 frame.shape.yellow()
2151 );
2152 }
2153 }
2154
2155 FrameMode::MapValue {
2157 index: key_frame_index,
2158 } if frame.is_fully_initialized() => {
2159 let mut key_frame = self.frames.remove(key_frame_index);
2163
2164 if !key_frame.istate.fields.is_any_set() {
2166 panic!("key is not initialized when popping value frame");
2167 }
2168
2169 #[cfg(feature = "log")]
2171 let frame_len = self.frames.len();
2172 let parent_frame = self.frames.last_mut().unwrap();
2173 let parent_shape = parent_frame.shape;
2174
2175 match parent_shape.def {
2177 Def::Map(_) => {
2178 if let Def::Map(map_def) = parent_shape.def {
2180 trace!(
2181 "[{}] Inserting key-value pair into map {}",
2182 frame_len,
2183 parent_shape.blue()
2184 );
2185 unsafe {
2186 (map_def.vtable.insert_fn)(
2188 parent_frame.data.assume_init(),
2189 key_frame.data.assume_init(),
2190 PtrMut::new(frame.data.as_mut_byte_ptr()),
2191 );
2192 self.mark_moved_out_of(&mut key_frame);
2193 self.mark_moved_out_of(&mut frame);
2194 }
2195 } else {
2196 panic!("parent frame is not a map type");
2197 }
2198 }
2199 _ => {
2200 panic!("Expected map or hash map, got {}", frame.shape);
2201 }
2202 }
2203 }
2204
2205 FrameMode::OptionSome => {
2207 if frame.is_fully_initialized() {
2208 trace!("Popping OptionSome (fully init'd)");
2209
2210 #[cfg(feature = "log")]
2212 let frames_len = self.frames.len();
2213 let parent_frame = self.frames.last_mut().unwrap();
2214 let parent_shape = parent_frame.shape;
2215
2216 match parent_shape.def {
2218 Def::Option(option_def) => {
2219 trace!(
2220 "[{}] Setting Some value in option {}",
2221 frames_len,
2222 parent_shape.blue()
2223 );
2224 unsafe {
2225 (option_def.vtable.init_some_fn)(
2227 parent_frame.data,
2228 PtrConst::new(frame.data.as_byte_ptr()),
2229 );
2230 trace!("Marking parent frame as fully initialized");
2231 parent_frame.mark_fully_initialized();
2232
2233 self.mark_moved_out_of(&mut frame);
2234 }
2235 }
2236 _ => {
2237 panic!(
2238 "Expected parent frame to be an option type, got {}",
2239 frame.shape
2240 );
2241 }
2242 }
2243 } else {
2244 trace!("Popping OptionSome (not fully init'd)");
2245 }
2246 }
2247
2248 FrameMode::MapKey => {}
2251
2252 FrameMode::Field => {}
2254
2255 _ => {}
2257 }
2258
2259 Ok(Some(frame))
2260 }
2261
2262 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
2266 match frame.shape.def {
2267 Def::Struct(sd) => {
2268 for f in sd.fields {
2269 let id = ValueId {
2270 shape: f.shape(),
2271 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
2272 };
2273 if let Some(istate) = self.istates.remove(&id) {
2274 let frame = Frame::recompose(id, istate);
2275 self.evict_tree(frame);
2276 } else {
2277 trace!("No istate found for field {}", f.name);
2278 }
2279 }
2280 }
2281 Def::Enum(_ed) => {
2282 if let Some(variant) = &frame.istate.variant {
2284 trace!(
2285 "Evicting enum {} variant '{}' fields",
2286 frame.shape.blue(),
2287 variant.name.yellow()
2288 );
2289 for field in variant.data.fields {
2291 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2293 let field_shape = field.shape();
2294 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2295
2296 if let Some(field_istate) = self.istates.remove(&field_id) {
2298 trace!(
2299 "Evicting field '{}' (shape {}) of enum variant '{}'",
2300 field.name.bright_blue(),
2301 field_shape.green(),
2302 variant.name.yellow()
2303 );
2304 let field_frame = Frame::recompose(field_id, field_istate);
2306 self.evict_tree(field_frame);
2308 } else {
2309 trace!(
2310 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
2311 field.name.red(),
2312 field_shape.red(),
2313 variant.name.yellow()
2314 );
2315 }
2316 }
2317 } else {
2318 trace!(
2320 "Enum {} has no variant selected, no fields to evict.",
2321 frame.shape.blue()
2322 );
2323 }
2324 }
2325 _ => {}
2326 }
2327 frame
2328 }
2329
2330 #[allow(rustdoc::broken_intra_doc_links)]
2331 pub fn path(&self) -> String {
2334 let mut path = String::from("$");
2335
2336 for (i, frame) in self.frames.iter().enumerate() {
2337 if i == 0 {
2339 continue;
2340 }
2341
2342 match frame.istate.mode {
2343 FrameMode::ListElement => {
2344 if let Some(index) = frame.istate.list_index {
2346 path.push_str(&format!("[{}]", index));
2347 } else {
2348 path.push_str("[?]");
2349 }
2350 }
2351 FrameMode::MapKey => {
2352 path.push_str(".key");
2353 }
2354 FrameMode::MapValue { index: _ } => {
2355 path.push_str(".value");
2356 }
2357 FrameMode::OptionSome => {
2358 path.push_str(".some");
2359 }
2360 FrameMode::OptionNone => {
2361 path.push_str(".none");
2362 }
2363 FrameMode::Root => {
2364 }
2366 FrameMode::Field => {
2367 if let Some(index) = frame.field_index_in_parent {
2369 if let Some(parent) = self.frames.get(i - 1) {
2371 if let Def::Struct(sd) = parent.shape.def {
2372 if index < sd.fields.len() {
2373 let field_name = sd.fields[index].name;
2374 path.push('.');
2375 path.push_str(field_name);
2376 }
2377 } else if let Def::Enum(_) = parent.shape.def {
2378 if let Some(variant) = &parent.istate.variant {
2379 if index < variant.data.fields.len() {
2380 let field_name = variant.data.fields[index].name;
2381 path.push('.');
2382 path.push_str(field_name);
2383 }
2384 }
2385 }
2386 }
2387 }
2388 }
2389 }
2390 }
2391
2392 path
2393 }
2394
2395 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
2397 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
2398 shape: <()>::SHAPE,
2399 operation: "tried to check if field is set, but there was no frame",
2400 })?;
2401
2402 match frame.shape.def {
2403 Def::Struct(ref sd) => {
2404 if index >= sd.fields.len() {
2405 return Err(ReflectError::FieldError {
2406 shape: frame.shape,
2407 field_error: FieldError::NoSuchField,
2408 });
2409 }
2410 Ok(frame.istate.fields.has(index))
2411 }
2412 Def::Enum(_) => {
2413 let variant = frame.istate.variant.as_ref().ok_or(
2414 ReflectError::OperationFailed {
2415 shape: frame.shape,
2416 operation: "tried to check if field is set, but no variant was selected",
2417 },
2418 )?;
2419 if index >= variant.data.fields.len() {
2420 return Err(ReflectError::FieldError {
2421 shape: frame.shape,
2422 field_error: FieldError::NoSuchField,
2423 });
2424 }
2425 Ok(frame.istate.fields.has(index))
2426 }
2427 _ => Err(ReflectError::WasNotA {
2428 expected: "struct or enum",
2429 actual: frame.shape,
2430 }),
2431 }
2432 }
2433}
2434
2435impl Drop for Wip<'_> {
2436 fn drop(&mut self) {
2437 trace!("🧹🧹🧹 WIP is dropping");
2438
2439 while let Some(frame) = self.frames.pop() {
2440 self.track(frame);
2441 }
2442
2443 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
2444 trace!("No root found, we probably built already");
2445 return;
2446 };
2447
2448 let root_id = *root_id;
2449 let root_istate = self.istates.remove(&root_id).unwrap();
2450 let root = Frame::recompose(root_id, root_istate);
2451 let mut to_clean = vec![root];
2452
2453 let mut _root_guard: Option<Guard> = None;
2454
2455 while let Some(mut frame) = to_clean.pop() {
2456 trace!(
2457 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
2458 frame.shape.blue(),
2459 frame.data.as_byte_ptr(),
2460 frame.istate.flags.bright_magenta(),
2461 frame.istate.mode.yellow(),
2462 if frame.is_fully_initialized() {
2463 "✅"
2464 } else {
2465 "❌"
2466 }
2467 );
2468
2469 if frame.istate.flags.contains(FrameFlags::MOVED) {
2470 trace!(
2471 "{}",
2472 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
2473 );
2474 continue;
2475 }
2476
2477 match frame.shape.def {
2478 Def::Struct(sd) => {
2479 if frame.is_fully_initialized() {
2480 trace!(
2481 "Dropping fully initialized struct: {} at {:p}",
2482 frame.shape.green(),
2483 frame.data.as_byte_ptr()
2484 );
2485 let frame = self.evict_tree(frame);
2486 unsafe { frame.drop_and_dealloc_if_needed() };
2487 } else {
2488 let num_fields = sd.fields.len();
2489 trace!(
2490 "De-initializing struct {} at {:p} field-by-field ({} fields)",
2491 frame.shape.yellow(),
2492 frame.data.as_byte_ptr(),
2493 num_fields.to_string().bright_cyan()
2494 );
2495 for i in 0..num_fields {
2496 if frame.istate.fields.has(i) {
2497 let field = sd.fields[i];
2498 let field_shape = field.shape();
2499 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
2500 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2501 trace!(
2502 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
2503 i.to_string().bright_cyan(),
2504 field.name.bright_blue(),
2505 frame.shape.blue(),
2506 field_shape.green(),
2507 field_ptr.as_byte_ptr()
2508 );
2509 let istate = self.istates.remove(&field_id).unwrap();
2510 let field_frame = Frame::recompose(field_id, istate);
2511 to_clean.push(field_frame);
2512 } else {
2513 trace!(
2514 "Field #{} '{}' of {} was NOT initialized, skipping",
2515 i.to_string().bright_cyan(),
2516 sd.fields[i].name.bright_red(),
2517 frame.shape.red()
2518 );
2519 }
2520 }
2521
2522 if frame.istate.mode == FrameMode::Root {
2524 if let Ok(layout) = frame.shape.layout.sized_layout() {
2525 _root_guard = Some(Guard {
2526 ptr: frame.data.as_mut_byte_ptr(),
2527 layout,
2528 });
2529 }
2530 }
2531 }
2532 }
2533 Def::Enum(_ed) => {
2534 trace!(
2535 "{}",
2536 format_args!(
2537 "TODO: handle enum deallocation for {} at {:p}",
2538 frame.shape.yellow(),
2539 frame.data.as_byte_ptr()
2540 )
2541 .magenta()
2542 );
2543
2544 if frame.istate.mode == FrameMode::Root {
2546 if let Ok(layout) = frame.shape.layout.sized_layout() {
2547 _root_guard = Some(Guard {
2548 ptr: frame.data.as_mut_byte_ptr(),
2549 layout,
2550 });
2551 }
2552 }
2553 }
2554 Def::Array(_)
2555 | Def::Slice(_)
2556 | Def::List(_)
2557 | Def::Map(_)
2558 | Def::SmartPointer(_)
2559 | Def::Scalar(_)
2560 | Def::FunctionPointer(_)
2561 | Def::Option(_) => {
2562 trace!(
2563 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
2564 frame.shape.cyan(),
2565 frame.shape.def,
2566 frame.istate.mode.yellow(),
2567 frame.data.as_byte_ptr(),
2568 );
2569
2570 if frame.is_fully_initialized() {
2571 unsafe { frame.drop_and_dealloc_if_needed() }
2572 } else {
2573 frame.dealloc_if_needed();
2574 }
2575 }
2576 _ => {}
2577 }
2578 }
2579
2580 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
2582 for frame_id in all_ids.drain(..) {
2583 let frame_istate = self.istates.remove(&frame_id).unwrap();
2584
2585 trace!(
2586 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
2587 frame_id.shape.cyan(),
2588 frame_id.ptr,
2589 frame_istate.mode.yellow()
2590 );
2591 let mut frame = Frame::recompose(frame_id, frame_istate);
2592
2593 if frame.is_fully_initialized() {
2594 trace!("It's fully initialized, we can drop it");
2595 unsafe { frame.drop_and_dealloc_if_needed() };
2596 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
2597 trace!("Not initialized but allocated, let's free it");
2598 frame.dealloc_if_needed();
2599 }
2600 }
2601 }
2602}