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