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, Shape, Variant,
14};
15use flat_map::FlatMap;
16
17use alloc::string::String;
18
19mod iset;
20pub use iset::*;
21
22mod put_f64;
23
24mod enum_;
25mod flat_map;
26
27mod heap_value;
28pub use heap_value::*;
29
30fn def_kind(def: &Def) -> &'static str {
31 match def {
32 Def::Scalar(_) => "scalar",
33 Def::Struct(_) => "struct",
34 Def::Map(_) => "map",
35 Def::List(_) => "list",
36 Def::Enum(_) => "enum",
37 Def::Option(_) => "option",
38 Def::SmartPointer(_) => "smart_ptr",
39 _ => "other",
40 }
41}
42
43pub struct Frame {
45 data: PtrUninit<'static>,
47
48 shape: &'static Shape,
50
51 field_index_in_parent: Option<usize>,
54
55 istate: IState,
59}
60
61impl Frame {
62 fn recompose(id: ValueId, istate: IState) -> Self {
64 Frame {
65 data: PtrUninit::new(id.ptr as *mut u8),
66 shape: id.shape,
67 field_index_in_parent: None,
68 istate,
69 }
70 }
71
72 fn dealloc_if_needed(&mut self) {
74 if self.istate.flags.contains(FrameFlags::ALLOCATED) {
75 trace!(
76 "[{}] {:p} => deallocating {}",
77 self.istate.depth,
78 self.data.as_mut_byte_ptr().magenta(),
79 self.shape.green(),
80 );
81 if self.shape.layout.size() != 0 {
82 unsafe {
83 alloc::alloc::dealloc(self.data.as_mut_byte_ptr(), self.shape.layout);
84 }
85 }
86 self.istate.flags.remove(FrameFlags::ALLOCATED);
87 } else {
88 trace!(
89 "[{}] {:p} => NOT deallocating {} (not ALLOCATED)",
90 self.istate.depth,
91 self.data.as_mut_byte_ptr().magenta(),
92 self.shape.green(),
93 );
94 }
95 }
96}
97
98struct DebugToDisplay<T>(T);
99
100impl<T> fmt::Debug for DebugToDisplay<T>
101where
102 T: fmt::Display,
103{
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 fmt::Display::fmt(&self.0, f)
106 }
107}
108
109impl fmt::Debug for Frame {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 f.debug_struct("Frame")
112 .field("shape", &DebugToDisplay(&self.shape))
113 .field("kind", &def_kind(&self.shape.def))
114 .field("index", &self.field_index_in_parent)
115 .field("mode", &self.istate.mode)
116 .finish()
117 }
118}
119
120impl Frame {
121 fn id(&self) -> ValueId {
123 ValueId::new(self.shape, self.data.as_byte_ptr())
124 }
125
126 fn is_fully_initialized(&self) -> bool {
128 match self.shape.def {
129 Def::Struct(sd) => self.istate.fields.are_all_set(sd.fields.len()),
130 Def::Enum(_) => match self.istate.variant.as_ref() {
131 None => false,
132 Some(v) => self.istate.fields.are_all_set(v.data.fields.len()),
133 },
134 _ => self.istate.fields.are_all_set(1),
135 }
136 }
137
138 unsafe fn drop_and_dealloc_if_needed(mut self) {
140 trace!(
141 "[Frame::drop] Dropping frame for shape {} at {:p}",
142 self.shape.blue(),
143 self.data.as_byte_ptr()
144 );
145 if let Some(drop_in_place) = self.shape.vtable.drop_in_place {
146 unsafe {
147 trace!(
148 "[Frame::drop] Invoking drop_in_place for shape {} at {:p}",
149 self.shape.green(),
150 self.data.as_byte_ptr()
151 );
152 drop_in_place(self.data.assume_init());
153 }
154 } else {
155 trace!(
156 "[Frame::drop] No drop_in_place function for shape {}",
157 self.shape.blue(),
158 );
159 }
160 self.dealloc_if_needed();
161 }
162
163 unsafe fn mark_fully_initialized(&mut self) {
165 match self.shape.def {
166 Def::Struct(sd) => {
167 self.istate.fields = ISet::all(sd.fields);
168 }
169 Def::Enum(_) => {
170 if let Some(variant) = &self.istate.variant {
171 self.istate.fields = ISet::all(variant.data.fields);
172 }
173 }
174 _ => {
175 self.istate.fields.set(0);
176 }
177 }
178 }
179}
180
181struct IState {
183 variant: Option<Variant>,
185
186 fields: ISet,
188
189 depth: usize,
191
192 mode: FrameMode,
194
195 flags: FrameFlags,
197
198 list_index: Option<usize>,
200
201 #[allow(dead_code)]
203 map_key: Option<String>,
204}
205
206bitflags! {
207 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209 pub struct FrameFlags: u64 {
210 const EMPTY = 0;
212
213 const ALLOCATED = 1 << 0;
215
216 const MOVED = 1 << 1;
220 }
221
222 }
224
225impl IState {
226 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
228 Self {
229 variant: None,
230 fields: Default::default(),
231 depth,
232 mode,
233 flags,
234 list_index: None,
235 map_key: None,
236 }
237 }
238
239 #[allow(dead_code)]
241 pub fn with_list_index(mut self, index: usize) -> Self {
242 self.list_index = Some(index);
243 self
244 }
245
246 #[allow(dead_code)]
248 pub fn with_map_key(mut self, key: String) -> Self {
249 self.map_key = Some(key);
250 self
251 }
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq)]
256pub enum FrameMode {
257 Root,
259 Field,
261 ListElement,
263 MapKey,
265 MapValue {
267 index: usize,
269 },
270 OptionSome,
272 OptionNone,
275}
276
277pub struct Wip<'a> {
279 frames: alloc::vec::Vec<Frame>,
281
282 istates: FlatMap<ValueId, IState>,
284
285 phantom: PhantomData<&'a ()>,
287}
288
289impl<'a> Wip<'a> {
290 pub fn put_peek<'mem>(self, peek: crate::Peek<'mem>) -> Result<Wip<'mem>, ReflectError>
292 where
293 'a: 'mem,
294 {
295 self.put_shape(peek.data, peek.shape)
296 }
297
298 pub fn frames_count(&self) -> usize {
300 self.frames.len()
301 }
302
303 pub fn alloc_shape(shape: &'static Shape) -> Self {
305 let data = shape.allocate();
306 Self {
307 frames: alloc::vec![Frame {
308 data,
309 shape,
310 field_index_in_parent: None,
311 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
312 }],
313 istates: Default::default(),
314 phantom: PhantomData,
315 }
316 }
317
318 pub fn alloc<S: Facet>() -> Self {
320 Self::alloc_shape(S::SHAPE)
321 }
322
323 fn track(&mut self, frame: Frame) {
324 if !frame.istate.flags.contains(FrameFlags::MOVED) {
330 self.istates.insert(frame.id(), frame.istate);
331 }
332 }
333
334 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame) {
335 frame.dealloc_if_needed();
336 ISet::clear(&mut frame.istate.fields);
337 frame.istate.variant = None;
338 frame.istate.flags.insert(FrameFlags::MOVED);
339 self.istates.remove(&frame.id());
342 }
343
344 pub fn shape(&self) -> &'static Shape {
346 self.frames.last().unwrap().shape
347 }
348
349 pub fn in_option(&self) -> bool {
351 let Some(frame) = self.frames.last() else {
352 return false;
353 };
354 matches!(frame.istate.mode, FrameMode::OptionSome)
355 }
356
357 pub fn mode(&self) -> FrameMode {
359 self.frames.last().unwrap().istate.mode
360 }
361
362 pub fn build(mut self) -> Result<HeapValue<'a>, ReflectError> {
364 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
365
366 while let Some(frame) = self.pop_inner() {
368 self.track(frame);
369 }
370
371 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
373 debug!("No root found, possibly already built or empty WIP");
374 return Err(ReflectError::OperationFailed {
375 shape: <()>::SHAPE,
376 operation: "tried to build a value but there was no root frame tracked",
377 });
378 };
379
380 let root_id = *root_id;
381 let root_istate = self
384 .istates
385 .remove(&root_id)
386 .expect("Root ID found but not present in istates, this is a bug"); let root_frame = Frame::recompose(root_id, root_istate);
389 let root_shape = root_frame.shape;
390 let root_data_ptr = root_frame.data; let guard = Guard {
397 ptr: root_data_ptr.as_mut_byte_ptr(),
398 layout: root_shape.layout,
399 };
400
401 let mut to_check = alloc::vec![root_frame];
403
404 while let Some(frame) = to_check.pop() {
406 trace!(
407 "Checking frame: shape={} at {:p}, flags={:?}, mode={:?}",
408 frame.shape.blue(),
409 frame.data.as_byte_ptr(),
410 frame.istate.flags.bright_magenta(),
411 frame.istate.mode,
412 );
413
414 if frame.istate.flags.contains(FrameFlags::MOVED) {
416 trace!(
417 "{}",
418 "Frame was moved out of, skipping initialization check".yellow()
419 );
420 continue;
421 }
422
423 match frame.shape.def {
425 Def::Struct(sd) => {
426 if !frame.is_fully_initialized() {
427 for i in 0..sd.fields.len() {
429 if !frame.istate.fields.has(i) {
430 let field = &sd.fields[i];
431 return Err(ReflectError::UninitializedField {
432 shape: frame.shape,
433 field_name: field.name,
434 });
435 }
436 }
437 unreachable!(
439 "Enum variant not fully initialized but couldn't find which field"
440 );
441 }
442
443 #[allow(clippy::unused_enumerate_index)]
445 for (_i, field) in sd.fields.iter().enumerate() {
446 let field_shape = field.shape();
447 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
448 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
449
450 if let Some(field_istate) = self.istates.remove(&field_id) {
451 debug!(
452 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
453 _i.to_string().bright_cyan(),
454 field.name.bright_blue(),
455 frame.shape.blue(),
456 field_shape.green(),
457 field_ptr.as_byte_ptr()
458 );
459 let field_frame = Frame::recompose(field_id, field_istate);
460 to_check.push(field_frame);
461 }
462 }
463 }
464 Def::Enum(_ed) => {
465 if let Some(variant) = &frame.istate.variant {
466 if !frame.istate.fields.are_all_set(variant.data.fields.len()) {
467 for (i, field) in variant.data.fields.iter().enumerate() {
469 if !frame.istate.fields.has(i) {
470 return Err(ReflectError::UninitializedEnumField {
471 shape: frame.shape,
472 variant_name: variant.name,
473 field_name: field.name,
474 });
475 }
476 }
477 unreachable!(
479 "Enum variant not fully initialized but couldn't find which field"
480 );
481 }
482
483 #[allow(clippy::unused_enumerate_index)]
485 for (_i, field) in variant.data.fields.iter().enumerate() {
486 let field_shape = field.shape();
487 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
491 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
492
493 if let Some(field_istate) = self.istates.remove(&field_id) {
494 debug!(
495 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
496 _i.to_string().bright_cyan(),
497 field.name.bright_blue(),
498 variant.name.yellow(),
499 frame.shape.blue(),
500 field_shape.green(),
501 field_ptr.as_byte_ptr()
502 );
503 let field_frame = Frame::recompose(field_id, field_istate);
504 to_check.push(field_frame);
505 }
506 }
507 } else {
508 return Err(ReflectError::NoVariantSelected { shape: frame.shape });
510 }
511 }
512 Def::List(_)
516 | Def::Map(_)
517 | Def::Option(_)
518 | Def::Scalar(_)
519 | Def::SmartPointer(_)
520 | Def::Array(_)
521 | Def::Slice(_) => {
522 if !frame.istate.fields.are_all_set(1) {
523 match frame.istate.mode {
525 FrameMode::OptionNone => {
526 return Err(ReflectError::UninitializedValue {
528 shape: frame.shape,
529 });
530 }
531 _ => {
533 return Err(ReflectError::UninitializedValue {
534 shape: frame.shape,
535 });
536 }
537 }
538 }
539 }
547 _ => {
549 if !frame.istate.fields.are_all_set(1) {
551 return Err(ReflectError::UninitializedValue { shape: frame.shape });
552 }
553 }
554 }
555 }
556
557 debug!("All reachable frames checked and initialized.");
559
560 let data = unsafe { root_data_ptr.assume_init() };
562 if let Some(invariant_fn) = root_shape.vtable.invariants {
563 debug!(
564 "Checking invariants for root shape {} at {:p}",
565 root_shape.green(),
566 data.as_byte_ptr()
567 );
568 if !unsafe { invariant_fn(PtrConst::new(data.as_byte_ptr())) } {
569 return Err(ReflectError::InvariantViolation {
570 invariant: "Custom validation function returned false",
571 });
572 }
573 } else {
574 debug!(
575 "No invariants to check for root shape {}",
576 root_shape.blue()
577 );
578 }
579
580 FlatMap::clear(&mut self.istates); Ok(HeapValue {
583 guard: Some(guard),
584 shape: root_shape,
585 phantom: PhantomData,
586 })
587 }
588
589 pub fn field(mut self, index: usize) -> Result<Self, ReflectError> {
601 let frame = self.frames.last_mut().unwrap();
602 let shape = frame.shape;
603
604 let (field, field_offset) = match shape.def {
605 Def::Struct(def) => {
606 if index >= def.fields.len() {
607 return Err(ReflectError::FieldError {
608 shape,
609 field_error: FieldError::NoSuchField,
610 });
611 }
612 let field = &def.fields[index];
613 (field, field.offset)
614 }
615 Def::Enum(_) => {
616 let Some(variant) = frame.istate.variant.as_ref() else {
617 return Err(ReflectError::OperationFailed {
618 shape,
619 operation: "tried to access a field but no variant was selected",
620 });
621 };
622
623 if index >= variant.data.fields.len() {
624 return Err(ReflectError::FieldError {
625 shape,
626 field_error: FieldError::NoSuchField,
627 });
628 }
629
630 let field = &variant.data.fields[index];
631 (field, field.offset)
632 }
633 _ => {
634 return Err(ReflectError::WasNotA {
635 expected: "struct or enum",
636 actual: shape,
637 });
638 }
639 };
640
641 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
642
643 let mut frame = Frame {
644 data: field_data,
645 shape: field.shape(),
646 field_index_in_parent: Some(index),
647 istate: IState::new(self.frames.len(), FrameMode::Field, FrameFlags::EMPTY),
649 };
650 debug!(
651 "[{}] Selecting field {} ({}#{}) of {}",
652 self.frames.len(),
653 field.name.blue(),
654 field.shape().green(),
655 index.yellow(),
656 shape.blue(),
657 );
658 if let Some(iset) = self.istates.remove(&frame.id()) {
659 trace!(
660 "[{}] Restoring saved state for {} (istate.mode = {:?}, istate.fields = {:?}, istate.flags = {:?}, istate.depth = {:?})",
661 self.frames.len(),
662 frame.id().shape.blue(),
663 iset.mode,
664 iset.fields,
665 iset.flags,
666 iset.depth
667 );
668 frame.istate = iset;
669 } else {
670 trace!(
671 "[{}] no saved state for field {} ({}#{}) of {}",
672 self.frames.len(),
673 field.name.blue(),
674 field.shape().green(),
675 index.yellow(),
676 shape.blue(),
677 );
678 }
679 self.frames.push(frame);
680 Ok(self)
681 }
682
683 pub fn field_index(&self, name: &str) -> Option<usize> {
695 let frame = self.frames.last()?;
696 match frame.shape.def {
697 Def::Struct(def) => def.fields.iter().position(|f| f.name == name),
698 Def::Enum(_) => {
699 let variant = frame.istate.variant.as_ref()?;
701 variant.data.fields.iter().position(|f| f.name == name)
702 }
703 _ => None,
704 }
705 }
706
707 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
719 let frame = self.frames.last().unwrap();
720 let shape = frame.shape;
721
722 if let Def::Enum(_) = shape.def {
724 if frame.istate.variant.is_none() {
725 return Err(ReflectError::OperationFailed {
726 shape,
727 operation: "tried to access a field by name but no variant was selected",
728 });
729 }
730 }
731
732 let index = self.field_index(name).ok_or(ReflectError::FieldError {
733 shape,
734 field_error: FieldError::NoSuchField,
735 })?;
736
737 self.field(index)
738 }
739
740 pub fn put<'val, T: Facet + 'val>(self, t: T) -> Result<Wip<'val>, ReflectError>
751 where
752 'a: 'val,
753 {
754 let shape = T::SHAPE;
755 let ptr_const = PtrConst::new(&t as *const T as *const u8);
756 let res = self.put_shape(ptr_const, shape);
757 core::mem::forget(t); res
759 }
760
761 pub fn current_is_type<T: Facet + 'static>(&self) -> bool {
763 self.frames
764 .last()
765 .is_some_and(|frame| frame.shape == T::SHAPE)
766 }
767
768 pub fn put_shape<'val>(
770 mut self,
771 src: PtrConst<'val>,
772 src_shape: &'static Shape,
773 ) -> Result<Wip<'val>, ReflectError>
774 where
775 'a: 'val,
776 {
777 let Some(frame) = self.frames.last_mut() else {
778 return Err(ReflectError::OperationFailed {
779 shape: src_shape,
780 operation: "tried to put a value but there was no frame to put into",
781 });
782 };
783
784 if frame.shape != src_shape {
786 if let Def::Option(od) = frame.shape.def {
789 if od.t() == src_shape {
791 debug!("Putting into an Option<T>!");
792 if frame.istate.fields.is_any_set() {
793 let data = unsafe { frame.data.assume_init() };
794 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
795 } else {
796 let data = frame.data;
797 unsafe { (od.vtable.init_some_fn)(data, src) };
798 }
799 unsafe {
800 frame.mark_fully_initialized();
801 }
802
803 let shape = frame.shape;
804 let index = frame.field_index_in_parent;
805
806 self.mark_field_as_initialized(shape, index)?;
808
809 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
810
811 return Ok(self);
812 }
813 }
814
815 return Err(ReflectError::WrongShape {
816 expected: frame.shape,
817 actual: src_shape,
818 });
819 }
820
821 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
823 debug!(
824 "De-initializing partially initialized fields for {}",
825 frame.shape
826 );
827
828 match frame.shape.def {
829 Def::Struct(sd) => {
830 for (i, field) in sd.fields.iter().enumerate() {
831 if frame.istate.fields.has(i) {
832 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
833 unsafe {
834 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
835 drop_fn(PtrMut::new(field_ptr));
836 }
837 }
838 }
839 }
840 }
841 Def::Enum(_) => {
842 if let Some(variant) = &frame.istate.variant {
843 for (i, field) in variant.data.fields.iter().enumerate() {
844 if frame.istate.fields.has(i) {
845 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
846 unsafe {
847 let field_ptr =
848 frame.data.as_mut_byte_ptr().add(field.offset);
849 drop_fn(PtrMut::new(field_ptr));
850 }
851 }
852 }
853 }
854 }
855 }
856 _ => {
857 }
859 }
860
861 frame.istate.variant = None;
863 ISet::clear(&mut frame.istate.fields);
864 }
865
866 unsafe {
867 frame.data.copy_from(src, frame.shape);
869 frame.mark_fully_initialized();
870 }
871
872 let shape = frame.shape;
873 let index = frame.field_index_in_parent;
874
875 self.mark_field_as_initialized(shape, index)?;
877
878 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
879
880 Ok(self)
881 }
882
883 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
885 let Some(frame) = self.frames.last_mut() else {
886 return Err(ReflectError::OperationFailed {
887 shape: <()>::SHAPE,
888 operation: "tried to parse value but there was no frame",
889 });
890 };
891
892 let shape = frame.shape;
893 let index = frame.field_index_in_parent;
894
895 let Some(parse_fn) = frame.shape.vtable.parse else {
896 return Err(ReflectError::OperationFailed {
897 shape: frame.shape,
898 operation: "type does not implement Parse",
899 });
900 };
901 match unsafe { (parse_fn)(s, frame.data) } {
902 Ok(_res) => {
903 unsafe {
904 frame.mark_fully_initialized();
905 }
906
907 self.mark_field_as_initialized(shape, index)?;
909
910 Ok(self)
911 }
912 Err(_) => Err(ReflectError::OperationFailed {
913 shape,
914 operation: "parsing",
915 }),
916 }
917 }
918
919 pub fn put_from_fn(mut self, default_in_place: DefaultInPlaceFn) -> Result<Self, ReflectError> {
921 let Some(frame) = self.frames.last_mut() else {
922 return Err(ReflectError::OperationFailed {
923 shape: <()>::SHAPE,
924 operation: "tried to put value from fn but there was no frame",
925 });
926 };
927
928 unsafe {
929 default_in_place(frame.data);
930 frame.mark_fully_initialized();
931 }
932
933 let shape = frame.shape;
934 let index = frame.field_index_in_parent;
935
936 self.mark_field_as_initialized(shape, index)?;
938
939 Ok(self)
940 }
941
942 pub fn put_default(self) -> Result<Self, ReflectError> {
944 let Some(frame) = self.frames.last() else {
945 return Err(ReflectError::OperationFailed {
946 shape: <()>::SHAPE,
947 operation: "tried to put default value but there was no frame",
948 });
949 };
950
951 let vtable = frame.shape.vtable;
952 let Some(default_in_place) = vtable.default_in_place else {
953 return Err(ReflectError::OperationFailed {
954 shape: frame.shape,
955 operation: "type does not implement Default",
956 });
957 };
958
959 self.put_from_fn(default_in_place)
960 }
961
962 fn mark_field_as_initialized(
964 &mut self,
965 shape: &'static Shape,
966 index: Option<usize>,
967 ) -> Result<(), ReflectError> {
968 if let Some(index) = index {
969 let parent_index = self.frames.len().saturating_sub(2);
970 #[cfg(feature = "log")]
971 let num_frames = self.frames.len();
972 let Some(parent) = self.frames.get_mut(parent_index) else {
973 return Err(ReflectError::OperationFailed {
974 shape,
975 operation: "was supposed to mark a field as initialized, but there was no parent frame",
976 });
977 };
978 #[cfg(feature = "log")]
979 let parent_shape = parent.shape;
980 trace!(
981 "[{}] {}.{} initialized with {}",
982 num_frames,
983 parent_shape.blue(),
984 index.yellow(),
985 shape.green()
986 );
987
988 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
989 return Err(ReflectError::OperationFailed {
990 shape,
991 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
992 });
993 }
994
995 if parent.istate.fields.has(index) {
996 return Err(ReflectError::OperationFailed {
997 shape,
998 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
999 });
1000 }
1001
1002 parent.istate.fields.set(index);
1003 }
1004 Ok(())
1005 }
1006
1007 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
1009 let frame = self.frames.last().unwrap();
1010 let shape = frame.shape;
1011
1012 match shape.def {
1013 Def::List(list_def) => Ok(list_def.t()),
1014 _ => Err(ReflectError::WasNotA {
1015 expected: "list or array",
1016 actual: shape,
1017 }),
1018 }
1019 }
1020
1021 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
1023 let frame = self.frames.last().unwrap();
1024 let shape = frame.shape;
1025
1026 match shape.def {
1027 Def::Map(map_def) => Ok(map_def.k),
1028 _ => Err(ReflectError::WasNotA {
1029 expected: "map",
1030 actual: shape,
1031 }),
1032 }
1033 }
1034
1035 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
1037 let Some(frame) = self.frames.last_mut() else {
1038 return Err(ReflectError::OperationFailed {
1039 shape: <()>::SHAPE,
1040 operation: "tried to create empty list but there was no frame",
1041 });
1042 };
1043
1044 if !matches!(frame.shape.def, Def::List(_)) {
1045 return Err(ReflectError::WasNotA {
1046 expected: "list or array",
1047 actual: frame.shape,
1048 });
1049 }
1050
1051 let vtable = frame.shape.vtable;
1052
1053 let Some(default_in_place) = vtable.default_in_place else {
1055 return Err(ReflectError::OperationFailed {
1056 shape: frame.shape,
1057 operation: "list type does not implement Default",
1058 });
1059 };
1060
1061 unsafe {
1062 default_in_place(frame.data);
1063 frame.mark_fully_initialized();
1064 }
1065
1066 let shape = frame.shape;
1067 let index = frame.field_index_in_parent;
1068
1069 self.mark_field_as_initialized(shape, index)?;
1071
1072 Ok(self)
1073 }
1074
1075 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1077 let Some(frame) = self.frames.last_mut() else {
1078 return Err(ReflectError::OperationFailed {
1079 shape: <()>::SHAPE,
1080 operation: "tried to create empty map but there was no frame",
1081 });
1082 };
1083
1084 if !matches!(frame.shape.def, Def::Map(_)) {
1085 return Err(ReflectError::WasNotA {
1086 expected: "map or hash map",
1087 actual: frame.shape,
1088 });
1089 }
1090
1091 let vtable = frame.shape.vtable;
1092
1093 let Some(default_in_place) = vtable.default_in_place else {
1095 return Err(ReflectError::OperationFailed {
1096 shape: frame.shape,
1097 operation: "map type does not implement Default",
1098 });
1099 };
1100
1101 unsafe {
1102 default_in_place(frame.data);
1103 frame.mark_fully_initialized();
1104 }
1105
1106 let shape = frame.shape;
1107 let index = frame.field_index_in_parent;
1108
1109 self.mark_field_as_initialized(shape, index)?;
1111
1112 Ok(self)
1113 }
1114
1115 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1117 let Some(frame) = self.frames.last_mut() else {
1118 return Err(ReflectError::OperationFailed {
1119 shape: <()>::SHAPE,
1120 operation: "tried to begin pushback but there was no frame",
1121 });
1122 };
1123
1124 if !matches!(frame.shape.def, Def::List(_)) {
1125 return Err(ReflectError::WasNotA {
1126 expected: "list or array",
1127 actual: frame.shape,
1128 });
1129 }
1130
1131 let vtable = frame.shape.vtable;
1132
1133 if !frame.istate.fields.has(0) {
1135 let Some(default_in_place) = vtable.default_in_place else {
1136 return Err(ReflectError::OperationFailed {
1137 shape: frame.shape,
1138 operation: "list type does not implement Default",
1139 });
1140 };
1141
1142 unsafe {
1143 default_in_place(frame.data);
1144 frame.istate.fields.set(0);
1145 }
1146 }
1147
1148 Ok(self)
1149 }
1150
1151 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1153 let Some(frame) = self.frames.last_mut() else {
1154 return Err(ReflectError::OperationFailed {
1155 shape: <()>::SHAPE,
1156 operation: "tried to begin map insertion but there was no frame",
1157 });
1158 };
1159
1160 if !matches!(frame.shape.def, Def::Map(_)) {
1161 return Err(ReflectError::WasNotA {
1162 expected: "map or hash map",
1163 actual: frame.shape,
1164 });
1165 }
1166
1167 let vtable = frame.shape.vtable;
1168
1169 if !frame.istate.fields.has(0) {
1171 let Some(default_in_place) = vtable.default_in_place else {
1172 return Err(ReflectError::OperationFailed {
1173 shape: frame.shape,
1174 operation: "map type does not implement Default",
1175 });
1176 };
1177
1178 unsafe {
1179 default_in_place(frame.data);
1180 frame.istate.fields.set(0);
1181 }
1182 }
1183
1184 Ok(self)
1185 }
1186
1187 pub fn push(mut self) -> Result<Self, ReflectError> {
1192 let frame = self.frames.last().unwrap();
1194 let list_shape = frame.shape;
1195
1196 if !matches!(list_shape.def, Def::List(_)) {
1197 return Err(ReflectError::WasNotA {
1198 expected: "list or array",
1199 actual: list_shape,
1200 });
1201 }
1202
1203 if !frame.istate.fields.has(0) {
1205 self = self.begin_pushback()?;
1206 }
1207
1208 let element_shape = self.element_shape()?;
1210
1211 let element_data = element_shape.allocate();
1213
1214 let element_frame = Frame {
1216 data: element_data,
1217 shape: element_shape,
1218 field_index_in_parent: None, istate: IState::new(
1220 self.frames.len(),
1221 FrameMode::ListElement,
1222 FrameFlags::ALLOCATED,
1223 ),
1224 };
1225
1226 trace!(
1227 "[{}] Pushing element of type {} to list {}",
1228 self.frames.len(),
1229 element_shape.green(),
1230 list_shape.blue(),
1231 );
1232
1233 self.frames.push(element_frame);
1234 Ok(self)
1235 }
1236
1237 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1239 let frame = self.frames.last().unwrap();
1241 let option_shape = frame.shape;
1242
1243 let Def::Option(option_def) = option_shape.def else {
1245 return Err(ReflectError::WasNotA {
1246 expected: "option",
1247 actual: option_shape,
1248 });
1249 };
1250
1251 let inner_shape = option_def.t();
1253
1254 let inner_data = inner_shape.allocate();
1256
1257 let inner_frame = Frame {
1259 data: inner_data,
1260 shape: inner_shape,
1261 field_index_in_parent: None,
1263 istate: IState::new(
1264 self.frames.len(),
1265 FrameMode::OptionSome,
1266 FrameFlags::ALLOCATED,
1268 ),
1269 };
1270
1271 trace!(
1272 "[{}] Pushing option frame for {}",
1273 self.frames.len(),
1274 option_shape.blue(),
1275 );
1276
1277 self.frames.push(inner_frame);
1278 Ok(self)
1279 }
1280
1281 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1291 let Some(frame) = self.frames.last_mut() else {
1293 return Err(ReflectError::OperationFailed {
1294 shape: <()>::SHAPE,
1295 operation: "tried to pop_some_push_none but there was no frame",
1296 });
1297 };
1298
1299 if frame.istate.mode != FrameMode::OptionSome {
1301 return Err(ReflectError::OperationFailed {
1302 shape: frame.shape,
1303 operation: "pop_some_push_none called, but frame was not in Option mode",
1304 });
1305 }
1306
1307 if frame.is_fully_initialized() {
1309 return Err(ReflectError::OperationFailed {
1310 shape: frame.shape,
1311 operation: "option frame already initialized, cannot pop_some_push_none",
1312 });
1313 }
1314
1315 frame.dealloc_if_needed();
1316
1317 let _frame = self.frames.pop().expect("frame already checked");
1319
1320 let parent_frame = self
1322 .frames
1323 .last_mut()
1324 .ok_or(ReflectError::OperationFailed {
1325 shape: <()>::SHAPE,
1326 operation: "tried to pop_some_push_none but there was no parent frame",
1327 })?;
1328
1329 unsafe {
1331 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1332 default_fn(parent_frame.data);
1333 } else {
1334 return Err(ReflectError::OperationFailed {
1335 shape: parent_frame.shape,
1336 operation: "option type does not implement Default",
1337 });
1338 }
1339 parent_frame.mark_fully_initialized();
1340 }
1341
1342 let Def::Option(od) = parent_frame.shape.def else {
1343 return Err(ReflectError::OperationFailed {
1344 shape: parent_frame.shape,
1345 operation: "pop_some_push_none and the parent isn't of type Option???",
1346 });
1347 };
1348
1349 let data = parent_frame.data;
1351
1352 let mut frame = Frame {
1353 data,
1354 shape: od.t(),
1355 field_index_in_parent: Some(0),
1356 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1357 };
1358 unsafe {
1359 frame.mark_fully_initialized();
1360 }
1361
1362 self.frames.push(frame);
1363
1364 Ok(self)
1365 }
1366
1367 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1372 let frame = self.frames.last().unwrap();
1374 let map_shape = frame.shape;
1375
1376 if !matches!(map_shape.def, Def::Map(_)) {
1377 return Err(ReflectError::WasNotA {
1378 expected: "map or hash map",
1379 actual: map_shape,
1380 });
1381 }
1382
1383 if !frame.istate.fields.has(0) {
1385 self = self.begin_map_insert()?;
1386 }
1387
1388 let key_shape = self.key_shape()?;
1390
1391 let key_data = key_shape.allocate();
1393
1394 let key_frame = Frame {
1396 data: key_data,
1397 shape: key_shape,
1398 field_index_in_parent: None,
1399 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1400 };
1401
1402 trace!(
1403 "[{}] Pushing key of type {} for map {}",
1404 self.frames.len(),
1405 key_shape.green(),
1406 map_shape.blue(),
1407 );
1408
1409 self.frames.push(key_frame);
1410 Ok(self)
1411 }
1412
1413 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1418 trace!("Wants to push map value. Frames = ");
1419 #[cfg(feature = "log")]
1420 for (i, f) in self.frames.iter().enumerate() {
1421 trace!("Frame {}: {:?}", i, f);
1422 }
1423
1424 if self.frames.len() < 2 {
1426 return Err(ReflectError::OperationFailed {
1427 shape: <()>::SHAPE,
1428 operation: "tried to push map value but there was no key frame",
1429 });
1430 }
1431
1432 let key_frame_index = self.frames.len() - 1;
1434 let key_frame = &self.frames[key_frame_index];
1435
1436 match key_frame.istate.mode {
1438 FrameMode::MapKey => {} _ => {
1440 return Err(ReflectError::OperationFailed {
1441 shape: key_frame.shape,
1442 operation: "current frame is not a map key",
1443 });
1444 }
1445 }
1446
1447 if !key_frame.is_fully_initialized() {
1449 return Err(ReflectError::OperationFailed {
1450 shape: key_frame.shape,
1451 operation: "map key is not fully initialized",
1452 });
1453 }
1454
1455 let map_frame_index = self.frames.len() - 2;
1457 let map_frame = &self.frames[map_frame_index];
1458 let map_shape = map_frame.shape;
1459
1460 let Def::Map(map_def) = map_shape.def else {
1461 return Err(ReflectError::WasNotA {
1462 expected: "map",
1463 actual: map_frame.shape,
1464 });
1465 };
1466
1467 let value_shape = map_def.v;
1468
1469 let value_data = value_shape.allocate();
1471
1472 let value_frame = Frame {
1474 data: value_data,
1475 shape: value_shape,
1476 field_index_in_parent: None,
1477 istate: IState::new(
1478 self.frames.len(),
1479 FrameMode::MapValue {
1480 index: key_frame_index,
1481 },
1482 FrameFlags::ALLOCATED,
1483 ),
1484 };
1485
1486 trace!(
1487 "[{}] Pushing value of type {} for map {} with key type {}",
1488 self.frames.len(),
1489 value_shape.green(),
1490 map_shape.blue(),
1491 key_frame.shape.yellow(),
1492 );
1493
1494 self.frames.push(value_frame);
1495 Ok(self)
1496 }
1497
1498 pub fn pop(mut self) -> Result<Self, ReflectError> {
1500 let Some(frame) = self.pop_inner() else {
1501 return Err(ReflectError::InvariantViolation {
1502 invariant: "No frame to pop",
1503 });
1504 };
1505 self.track(frame);
1506 Ok(self)
1507 }
1508
1509 fn pop_inner(&mut self) -> Option<Frame> {
1510 let mut frame = self.frames.pop()?;
1511 #[cfg(feature = "log")]
1512 let frame_shape = frame.shape;
1513
1514 let init = frame.is_fully_initialized();
1515 trace!(
1516 "[{}] {} popped, {} initialized",
1517 self.frames.len(),
1518 frame_shape.blue(),
1519 if init {
1520 "✅ fully".style(owo_colors::Style::new().green())
1521 } else {
1522 "🚧 partially".style(owo_colors::Style::new().red())
1523 }
1524 );
1525 if init {
1526 if let Some(parent) = self.frames.last_mut() {
1527 if let Some(index) = frame.field_index_in_parent {
1528 parent.istate.fields.set(index);
1529 }
1530 }
1531 }
1532
1533 match frame.istate.mode {
1535 FrameMode::ListElement => {
1537 if frame.is_fully_initialized() {
1538 #[cfg(feature = "log")]
1541 let frame_len = self.frames.len();
1542
1543 let parent_frame = self.frames.last_mut().unwrap();
1545 let parent_shape = parent_frame.shape;
1546
1547 match parent_shape.def {
1549 Def::List(_) => {
1550 if let Def::List(list_def) = parent_shape.def {
1552 let list_vtable = list_def.vtable;
1553 trace!(
1554 "[{}] Pushing element to list {}",
1555 frame_len,
1556 parent_shape.blue()
1557 );
1558 unsafe {
1559 (list_vtable.push)(
1561 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1562 PtrMut::new(frame.data.as_mut_byte_ptr()),
1563 );
1564 self.mark_moved_out_of(&mut frame);
1565 }
1566 } else {
1567 panic!("parent frame is not a list type");
1568 }
1569 }
1570 _ => {
1571 panic!("Expected list or array, got {}", frame.shape);
1572 }
1573 }
1574 }
1575 }
1576
1577 FrameMode::MapValue {
1579 index: key_frame_index,
1580 } if frame.is_fully_initialized() => {
1581 let mut key_frame = self.frames.remove(key_frame_index);
1585
1586 if !key_frame.istate.fields.is_any_set() {
1588 panic!("key is not initialized when popping value frame");
1589 }
1590
1591 #[cfg(feature = "log")]
1593 let frame_len = self.frames.len();
1594 let parent_frame = self.frames.last_mut().unwrap();
1595 let parent_shape = parent_frame.shape;
1596
1597 match parent_shape.def {
1599 Def::Map(_) => {
1600 if let Def::Map(map_def) = parent_shape.def {
1602 trace!(
1603 "[{}] Inserting key-value pair into map {}",
1604 frame_len,
1605 parent_shape.blue()
1606 );
1607 unsafe {
1608 (map_def.vtable.insert_fn)(
1610 parent_frame.data.assume_init(),
1611 key_frame.data.assume_init(),
1612 PtrMut::new(frame.data.as_mut_byte_ptr()),
1613 );
1614 self.mark_moved_out_of(&mut key_frame);
1615 self.mark_moved_out_of(&mut frame);
1616 }
1617 } else {
1618 panic!("parent frame is not a map type");
1619 }
1620 }
1621 _ => {
1622 panic!("Expected map or hash map, got {}", frame.shape);
1623 }
1624 }
1625 }
1626
1627 FrameMode::OptionSome => {
1629 if frame.is_fully_initialized() {
1630 trace!("Popping OptionSome (fully init'd)");
1631
1632 #[cfg(feature = "log")]
1634 let frames_len = self.frames.len();
1635 let parent_frame = self.frames.last_mut().unwrap();
1636 let parent_shape = parent_frame.shape;
1637
1638 match parent_shape.def {
1640 Def::Option(option_def) => {
1641 trace!(
1642 "[{}] Setting Some value in option {}",
1643 frames_len,
1644 parent_shape.blue()
1645 );
1646 unsafe {
1647 (option_def.vtable.init_some_fn)(
1649 parent_frame.data,
1650 PtrConst::new(frame.data.as_byte_ptr()),
1651 );
1652 trace!("Marking parent frame as fully initialized");
1653 parent_frame.mark_fully_initialized();
1654
1655 self.mark_moved_out_of(&mut frame);
1656 }
1657 }
1658 _ => {
1659 panic!(
1660 "Expected parent frame to be an option type, got {}",
1661 frame.shape
1662 );
1663 }
1664 }
1665 } else {
1666 trace!("Popping OptionSome (not fully init'd)");
1667 }
1668 }
1669
1670 FrameMode::MapKey => {}
1673
1674 FrameMode::Field => {}
1676
1677 _ => {}
1679 }
1680
1681 Some(frame)
1682 }
1683
1684 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
1688 match frame.shape.def {
1689 Def::Struct(sd) => {
1690 for f in sd.fields {
1691 let id = ValueId {
1692 shape: f.shape(),
1693 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1694 };
1695 if let Some(istate) = self.istates.remove(&id) {
1696 let frame = Frame::recompose(id, istate);
1697 self.evict_tree(frame);
1698 } else {
1699 trace!("No istate found for field {}", f.name);
1700 }
1701 }
1702 }
1703 Def::Enum(_ed) => {
1704 if let Some(variant) = &frame.istate.variant {
1706 trace!(
1707 "Evicting enum {} variant '{}' fields",
1708 frame.shape.blue(),
1709 variant.name.yellow()
1710 );
1711 for field in variant.data.fields {
1713 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1715 let field_shape = field.shape();
1716 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1717
1718 if let Some(field_istate) = self.istates.remove(&field_id) {
1720 trace!(
1721 "Evicting field '{}' (shape {}) of enum variant '{}'",
1722 field.name.bright_blue(),
1723 field_shape.green(),
1724 variant.name.yellow()
1725 );
1726 let field_frame = Frame::recompose(field_id, field_istate);
1728 self.evict_tree(field_frame);
1730 } else {
1731 trace!(
1732 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1733 field.name.red(),
1734 field_shape.red(),
1735 variant.name.yellow()
1736 );
1737 }
1738 }
1739 } else {
1740 trace!(
1742 "Enum {} has no variant selected, no fields to evict.",
1743 frame.shape.blue()
1744 );
1745 }
1746 }
1747 _ => {}
1748 }
1749 frame
1750 }
1751
1752 #[allow(rustdoc::broken_intra_doc_links)]
1753 pub fn path(&self) -> String {
1756 let mut path = String::from("$");
1757
1758 for (i, frame) in self.frames.iter().enumerate() {
1759 if i == 0 {
1761 continue;
1762 }
1763
1764 match frame.istate.mode {
1765 FrameMode::ListElement => {
1766 if let Some(index) = frame.istate.list_index {
1768 path.push_str(&format!("[{}]", index));
1769 } else {
1770 path.push_str("[?]");
1771 }
1772 }
1773 FrameMode::MapKey => {
1774 path.push_str(".key");
1775 }
1776 FrameMode::MapValue { index: _ } => {
1777 path.push_str(".value");
1778 }
1779 FrameMode::OptionSome => {
1780 path.push_str(".some");
1781 }
1782 FrameMode::OptionNone => {
1783 path.push_str(".none");
1784 }
1785 FrameMode::Root => {
1786 }
1788 FrameMode::Field => {
1789 if let Some(index) = frame.field_index_in_parent {
1791 if let Some(parent) = self.frames.get(i - 1) {
1793 if let Def::Struct(sd) = parent.shape.def {
1794 if index < sd.fields.len() {
1795 let field_name = sd.fields[index].name;
1796 path.push('.');
1797 path.push_str(field_name);
1798 }
1799 } else if let Def::Enum(_) = parent.shape.def {
1800 if let Some(variant) = &parent.istate.variant {
1801 if index < variant.data.fields.len() {
1802 let field_name = variant.data.fields[index].name;
1803 path.push('.');
1804 path.push_str(field_name);
1805 }
1806 }
1807 }
1808 }
1809 }
1810 }
1811 }
1812 }
1813
1814 path
1815 }
1816
1817 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
1819 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
1820 shape: <()>::SHAPE,
1821 operation: "tried to check if field is set, but there was no frame",
1822 })?;
1823
1824 match frame.shape.def {
1825 Def::Struct(ref sd) => {
1826 if index >= sd.fields.len() {
1827 return Err(ReflectError::FieldError {
1828 shape: frame.shape,
1829 field_error: FieldError::NoSuchField,
1830 });
1831 }
1832 Ok(frame.istate.fields.has(index))
1833 }
1834 Def::Enum(_) => {
1835 let variant = frame.istate.variant.as_ref().ok_or(
1836 ReflectError::OperationFailed {
1837 shape: frame.shape,
1838 operation: "tried to check if field is set, but no variant was selected",
1839 },
1840 )?;
1841 if index >= variant.data.fields.len() {
1842 return Err(ReflectError::FieldError {
1843 shape: frame.shape,
1844 field_error: FieldError::NoSuchField,
1845 });
1846 }
1847 Ok(frame.istate.fields.has(index))
1848 }
1849 _ => Err(ReflectError::WasNotA {
1850 expected: "struct or enum",
1851 actual: frame.shape,
1852 }),
1853 }
1854 }
1855}
1856
1857impl Drop for Wip<'_> {
1858 fn drop(&mut self) {
1859 trace!("🧹🧹🧹 WIP is dropping");
1860
1861 while let Some(frame) = self.frames.pop() {
1862 self.track(frame);
1863 }
1864
1865 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
1866 trace!("No root found, we probably built already");
1867 return;
1868 };
1869
1870 let root_id = *root_id;
1871 let root_istate = self.istates.remove(&root_id).unwrap();
1872 let root = Frame::recompose(root_id, root_istate);
1873 let mut to_clean = vec![root];
1874
1875 let mut _root_guard: Option<Guard> = None;
1876
1877 while let Some(mut frame) = to_clean.pop() {
1878 trace!(
1879 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
1880 frame.shape.blue(),
1881 frame.data.as_byte_ptr(),
1882 frame.istate.flags.bright_magenta(),
1883 frame.istate.mode.yellow(),
1884 if frame.is_fully_initialized() {
1885 "✅"
1886 } else {
1887 "❌"
1888 }
1889 );
1890
1891 if frame.istate.flags.contains(FrameFlags::MOVED) {
1892 trace!(
1893 "{}",
1894 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
1895 );
1896 continue;
1897 }
1898
1899 match frame.shape.def {
1900 Def::Struct(sd) => {
1901 if frame.is_fully_initialized() {
1902 trace!(
1903 "Dropping fully initialized struct: {} at {:p}",
1904 frame.shape.green(),
1905 frame.data.as_byte_ptr()
1906 );
1907 let frame = self.evict_tree(frame);
1908 unsafe { frame.drop_and_dealloc_if_needed() };
1909 } else {
1910 let num_fields = sd.fields.len();
1911 trace!(
1912 "De-initializing struct {} at {:p} field-by-field ({} fields)",
1913 frame.shape.yellow(),
1914 frame.data.as_byte_ptr(),
1915 num_fields.to_string().bright_cyan()
1916 );
1917 for i in 0..num_fields {
1918 if frame.istate.fields.has(i) {
1919 let field = sd.fields[i];
1920 let field_shape = field.shape();
1921 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
1922 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1923 trace!(
1924 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
1925 i.to_string().bright_cyan(),
1926 field.name.bright_blue(),
1927 frame.shape.blue(),
1928 field_shape.green(),
1929 field_ptr.as_byte_ptr()
1930 );
1931 let istate = self.istates.remove(&field_id).unwrap();
1932 let field_frame = Frame::recompose(field_id, istate);
1933 to_clean.push(field_frame);
1934 } else {
1935 trace!(
1936 "Field #{} '{}' of {} was NOT initialized, skipping",
1937 i.to_string().bright_cyan(),
1938 sd.fields[i].name.bright_red(),
1939 frame.shape.red()
1940 );
1941 }
1942 }
1943
1944 if frame.istate.mode == FrameMode::Root {
1946 _root_guard = Some(Guard {
1947 ptr: frame.data.as_mut_byte_ptr(),
1948 layout: frame.shape.layout,
1949 });
1950 }
1951 }
1952 }
1953 Def::Enum(_ed) => {
1954 trace!(
1955 "{}",
1956 format!(
1957 "TODO: handle enum deallocation for {} at {:p}",
1958 frame.shape.yellow(),
1959 frame.data.as_byte_ptr()
1960 )
1961 .magenta()
1962 );
1963
1964 if frame.istate.mode == FrameMode::Root {
1966 _root_guard = Some(Guard {
1967 ptr: frame.data.as_mut_byte_ptr(),
1968 layout: frame.shape.layout,
1969 });
1970 }
1971 }
1972 Def::Array(_)
1973 | Def::Slice(_)
1974 | Def::List(_)
1975 | Def::Map(_)
1976 | Def::SmartPointer(_)
1977 | Def::Scalar(_)
1978 | Def::Option(_) => {
1979 trace!(
1980 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
1981 frame.shape.cyan(),
1982 frame.shape.def,
1983 frame.istate.mode.yellow(),
1984 frame.data.as_byte_ptr(),
1985 );
1986
1987 if frame.is_fully_initialized() {
1988 unsafe { frame.drop_and_dealloc_if_needed() }
1989 } else {
1990 frame.dealloc_if_needed();
1991 }
1992 }
1993 _ => {}
1994 }
1995 }
1996
1997 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
1999 for frame_id in all_ids.drain(..) {
2000 let frame_istate = self.istates.remove(&frame_id).unwrap();
2001
2002 trace!(
2003 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
2004 frame_id.shape.cyan(),
2005 frame_id.ptr,
2006 frame_istate.mode.yellow()
2007 );
2008 let mut frame = Frame::recompose(frame_id, frame_istate);
2009
2010 if frame.is_fully_initialized() {
2011 trace!("It's fully initialized, we can drop it");
2012 unsafe { frame.drop_and_dealloc_if_needed() };
2013 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
2014 trace!("Not initialized but allocated, let's free it");
2015 frame.dealloc_if_needed();
2016 }
2017 }
2018 }
2019}