1use crate::{ReflectError, ValueId};
2use alloc::{format, string::ToString};
3use alloc::{vec, vec::Vec};
4use bitflags::bitflags;
5use core::{fmt, marker::PhantomData};
6use facet_ansi::Stylize;
7use facet_core::{Def, Facet, FieldError, PtrConst, PtrMut, PtrUninit, Shape, Variant};
8use flat_map::FlatMap;
9use log::trace;
10
11mod iset;
12pub use iset::*;
13
14mod enum_;
15mod flat_map;
16
17mod heap_value;
18pub use heap_value::*;
19
20fn def_kind(def: &Def) -> &'static str {
21 match def {
22 Def::Scalar(_) => "scalar",
23 Def::Struct(_) => "struct",
24 Def::Map(_) => "map",
25 Def::List(_) => "list",
26 Def::Enum(_) => "enum",
27 Def::Option(_) => "option",
28 Def::SmartPointer(_) => "smart_ptr",
29 _ => "other",
30 }
31}
32
33pub struct Frame {
35 data: PtrUninit<'static>,
37
38 shape: &'static Shape,
40
41 field_index_in_parent: Option<usize>,
44
45 istate: IState,
49}
50
51impl Frame {
52 fn recompose(id: ValueId, istate: IState) -> Self {
54 Frame {
55 data: PtrUninit::new(id.ptr as *mut u8),
56 shape: id.shape,
57 field_index_in_parent: None,
58 istate,
59 }
60 }
61
62 fn dealloc_if_needed(&mut self) {
64 if self.istate.flags.contains(FrameFlags::ALLOCATED) {
65 trace!(
66 "[{}] {:p} => deallocating {}",
67 self.istate.depth,
68 self.data.as_mut_byte_ptr().magenta(),
69 self.shape.green(),
70 );
71 if self.shape.layout.size() != 0 {
72 trace!("Ok I swear we're deallocating it");
73 unsafe {
74 alloc::alloc::dealloc(self.data.as_mut_byte_ptr(), self.shape.layout);
75 }
76 }
77 self.istate.flags.remove(FrameFlags::ALLOCATED);
78 } else {
79 trace!(
80 "[{}] {:p} => NOT deallocating {} (not ALLOCATED)",
81 self.istate.depth,
82 self.data.as_mut_byte_ptr().magenta(),
83 self.shape.green(),
84 );
85 }
86 }
87}
88
89struct DebugToDisplay<T>(T);
90
91impl<T> fmt::Debug for DebugToDisplay<T>
92where
93 T: fmt::Display,
94{
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 fmt::Display::fmt(&self.0, f)
97 }
98}
99
100impl fmt::Debug for Frame {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 f.debug_struct("Frame")
103 .field("shape", &DebugToDisplay(&self.shape))
104 .field("kind", &def_kind(&self.shape.def))
105 .field("index", &self.field_index_in_parent)
106 .field("mode", &self.istate.mode)
107 .finish()
108 }
109}
110
111impl Frame {
112 fn id(&self) -> ValueId {
114 ValueId::new(self.shape, self.data.as_byte_ptr())
115 }
116
117 fn is_fully_initialized(&self) -> bool {
119 match self.shape.def {
120 Def::Struct(sd) => self.istate.fields.are_all_set(sd.fields.len()),
121 Def::Enum(_) => match self.istate.variant.as_ref() {
122 None => false,
123 Some(v) => self.istate.fields.are_all_set(v.data.fields.len()),
124 },
125 _ => self.istate.fields.are_all_set(1),
126 }
127 }
128
129 unsafe fn drop_and_dealloc_if_needed(mut self) {
131 trace!(
132 "[Frame::drop] Dropping frame for shape {} at {:p}",
133 self.shape.blue(),
134 self.data.as_byte_ptr()
135 );
136 if let Some(drop_in_place) = self.shape.vtable.drop_in_place {
137 unsafe {
138 trace!(
139 "[Frame::drop] Invoking drop_in_place for shape {} at {:p}",
140 self.shape.green(),
141 self.data.as_byte_ptr()
142 );
143 drop_in_place(self.data.assume_init());
144 }
145 } else {
146 trace!(
147 "[Frame::drop] No drop_in_place function for shape {}",
148 self.shape.blue(),
149 );
150 }
151 self.dealloc_if_needed();
152 }
153
154 unsafe fn mark_fully_initialized(&mut self) {
156 match self.shape.def {
157 Def::Struct(sd) => {
158 self.istate.fields = ISet::all(sd.fields);
159 }
160 Def::Enum(_) => {
161 if let Some(variant) = &self.istate.variant {
162 self.istate.fields = ISet::all(variant.data.fields);
163 }
164 }
165 _ => {
166 self.istate.fields.set(0);
167 }
168 }
169 }
170
171 unsafe fn mark_uninitialized(&mut self) {
173 self.istate.fields.clear();
174 self.istate.variant = None;
175 }
176
177 unsafe fn mark_moved_out_of(&mut self) {
178 self.dealloc_if_needed();
179 unsafe { self.mark_uninitialized() };
180 self.istate.flags.insert(FrameFlags::MOVED);
181 }
182}
183
184struct IState {
186 variant: Option<Variant>,
188
189 fields: ISet,
191
192 depth: usize,
194
195 mode: FrameMode,
197
198 flags: FrameFlags,
200}
201
202bitflags! {
203 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
205 pub struct FrameFlags: u64 {
206 const EMPTY = 0;
208
209 const ALLOCATED = 1 << 0;
211
212 const MOVED = 1 << 1;
216 }
217
218 }
220
221impl IState {
222 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
224 Self {
225 variant: None,
226 fields: Default::default(),
227 depth,
228 mode,
229 flags,
230 }
231 }
232}
233
234#[derive(Debug, Clone, Copy, PartialEq, Eq)]
236pub enum FrameMode {
237 Root,
239 Normal,
241 ListElement,
243 MapKey,
245 MapValue {
247 index: usize,
249 },
250 OptionSome,
252 OptionNone,
255}
256
257pub struct Wip<'a> {
259 frames: alloc::vec::Vec<Frame>,
261
262 istates: FlatMap<ValueId, IState>,
264
265 phantom: PhantomData<&'a ()>,
267}
268
269impl<'a> Wip<'a> {
270 pub fn frames_count(&self) -> usize {
272 self.frames.len()
273 }
274
275 pub fn alloc_shape(shape: &'static Shape) -> Self {
277 let data = shape.allocate();
278 Self {
279 frames: alloc::vec![Frame {
280 data,
281 shape,
282 field_index_in_parent: None,
283 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
284 }],
285 istates: Default::default(),
286 phantom: PhantomData,
287 }
288 }
289
290 pub fn alloc<S: Facet>() -> Self {
292 Self::alloc_shape(S::SHAPE)
293 }
294
295 fn track(&mut self, frame: Frame) {
296 if frame.istate.flags.contains(FrameFlags::MOVED) {
297 return;
299 }
300 self.istates.insert(frame.id(), frame.istate);
301 }
302
303 pub fn shape(&self) -> &'static Shape {
305 self.frames.last().unwrap().shape
306 }
307
308 pub fn in_option(&self) -> bool {
310 let Some(frame) = self.frames.last() else {
311 return false;
312 };
313 matches!(frame.istate.mode, FrameMode::OptionSome)
314 }
315
316 pub fn mode(&self) -> FrameMode {
318 self.frames.last().unwrap().istate.mode
319 }
320
321 pub fn build(mut self) -> Result<HeapValue<'a>, ReflectError> {
323 trace!("[{}] ⚒️ It's BUILD time", self.frames.len());
324
325 while let Some(frame) = self.pop_inner() {
327 self.track(frame);
328 }
329
330 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
332 trace!("No root found, possibly already built or empty WIP");
333 return Err(ReflectError::OperationFailed {
334 shape: <()>::SHAPE,
335 operation: "tried to build a value but there was no root frame tracked",
336 });
337 };
338
339 let root_id = *root_id;
340 let root_istate = self
343 .istates
344 .remove(&root_id)
345 .expect("Root ID found but not present in istates, this is a bug"); let root_frame = Frame::recompose(root_id, root_istate);
348 let root_shape = root_frame.shape;
349 let root_data_ptr = root_frame.data; let guard = Guard {
356 ptr: root_data_ptr.as_mut_byte_ptr(),
357 layout: root_shape.layout,
358 };
359
360 let mut to_check = alloc::vec![root_frame];
362
363 while let Some(frame) = to_check.pop() {
365 trace!(
366 "Checking frame: shape={} at {:p}, flags={:?}, mode={:?}",
367 frame.shape.blue(),
368 frame.data.as_byte_ptr(),
369 frame.istate.flags.bright_magenta(),
370 frame.istate.mode,
371 );
372
373 if frame.istate.flags.contains(FrameFlags::MOVED) {
375 trace!(
376 "{}",
377 "Frame was moved out of, skipping initialization check".yellow()
378 );
379 continue;
380 }
381
382 match frame.shape.def {
384 Def::Struct(sd) => {
385 if !frame.is_fully_initialized() {
386 for i in 0..sd.fields.len() {
388 if !frame.istate.fields.has(i) {
389 let field = &sd.fields[i];
390 return Err(ReflectError::UninitializedField {
391 shape: frame.shape,
392 field_name: field.name,
393 });
394 }
395 }
396 unreachable!(
398 "Enum variant not fully initialized but couldn't find which field"
399 );
400 }
401
402 for (i, field) in sd.fields.iter().enumerate() {
404 let field_shape = field.shape();
405 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
406 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
407
408 if let Some(field_istate) = self.istates.remove(&field_id) {
409 trace!(
410 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
411 i.to_string().bright_cyan(),
412 field.name.bright_blue(),
413 frame.shape.blue(),
414 field_shape.green(),
415 field_ptr.as_byte_ptr()
416 );
417 let field_frame = Frame::recompose(field_id, field_istate);
418 to_check.push(field_frame);
419 }
420 }
421 }
422 Def::Enum(_ed) => {
423 if let Some(variant) = &frame.istate.variant {
424 if !frame.istate.fields.are_all_set(variant.data.fields.len()) {
425 for (i, field) in variant.data.fields.iter().enumerate() {
427 if !frame.istate.fields.has(i) {
428 return Err(ReflectError::UninitializedEnumField {
429 shape: frame.shape,
430 variant_name: variant.name,
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 for (i, field) in variant.data.fields.iter().enumerate() {
443 let field_shape = field.shape();
444 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 trace!(
452 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
453 i.to_string().bright_cyan(),
454 field.name.bright_blue(),
455 variant.name.yellow(),
456 frame.shape.blue(),
457 field_shape.green(),
458 field_ptr.as_byte_ptr()
459 );
460 let field_frame = Frame::recompose(field_id, field_istate);
461 to_check.push(field_frame);
462 }
463 }
464 } else {
465 return Err(ReflectError::NoVariantSelected { shape: frame.shape });
467 }
468 }
469 Def::List(_)
473 | Def::Map(_)
474 | Def::Option(_)
475 | Def::Scalar(_)
476 | Def::SmartPointer(_)
477 | Def::Array(_)
478 | Def::Slice(_) => {
479 if !frame.istate.fields.are_all_set(1) {
480 match frame.istate.mode {
482 FrameMode::OptionNone => {
483 return Err(ReflectError::UninitializedValue {
485 shape: frame.shape,
486 });
487 }
488 _ => {
490 return Err(ReflectError::UninitializedValue {
491 shape: frame.shape,
492 });
493 }
494 }
495 }
496 }
504 _ => {
506 if !frame.istate.fields.are_all_set(1) {
508 return Err(ReflectError::UninitializedValue { shape: frame.shape });
509 }
510 }
511 }
512 }
513
514 trace!("All reachable frames checked and initialized.");
516
517 let data = unsafe { root_data_ptr.assume_init() };
519 if let Some(invariant_fn) = root_shape.vtable.invariants {
520 trace!(
521 "Checking invariants for root shape {} at {:p}",
522 root_shape.green(),
523 data.as_byte_ptr()
524 );
525 if !unsafe { invariant_fn(PtrConst::new(data.as_byte_ptr())) } {
526 return Err(ReflectError::InvariantViolation {
527 invariant: "Custom validation function returned false",
528 });
529 }
530 } else {
531 trace!(
532 "No invariants to check for root shape {}",
533 root_shape.blue()
534 );
535 }
536
537 self.istates.clear(); Ok(HeapValue {
540 guard: Some(guard),
541 shape: root_shape,
542 phantom: PhantomData,
543 })
544 }
545
546 pub fn field(mut self, index: usize) -> Result<Self, ReflectError> {
558 let frame = self.frames.last_mut().unwrap();
559 let shape = frame.shape;
560
561 let (field, field_offset) = match shape.def {
562 Def::Struct(def) => {
563 if index >= def.fields.len() {
564 return Err(ReflectError::FieldError {
565 shape,
566 field_error: FieldError::NoSuchField,
567 });
568 }
569 let field = &def.fields[index];
570 (field, field.offset)
571 }
572 Def::Enum(_) => {
573 let Some(variant) = frame.istate.variant.as_ref() else {
574 return Err(ReflectError::OperationFailed {
575 shape,
576 operation: "tried to access a field but no variant was selected",
577 });
578 };
579
580 if index >= variant.data.fields.len() {
581 return Err(ReflectError::FieldError {
582 shape,
583 field_error: FieldError::NoSuchField,
584 });
585 }
586
587 let field = &variant.data.fields[index];
588 (field, field.offset)
589 }
590 _ => {
591 return Err(ReflectError::WasNotA {
592 expected: "struct or enum",
593 actual: shape,
594 });
595 }
596 };
597
598 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
599
600 let mut frame = Frame {
601 data: field_data,
602 shape: field.shape(),
603 field_index_in_parent: Some(index),
604 istate: IState::new(self.frames.len(), FrameMode::Normal, FrameFlags::EMPTY),
606 };
607 trace!(
608 "[{}] Selecting field {} ({}#{}) of {}",
609 self.frames.len(),
610 field.name.blue(),
611 field.shape().green(),
612 index.yellow(),
613 shape.blue(),
614 );
615 if let Some(iset) = self.istates.remove(&frame.id()) {
616 trace!(
617 "[{}] Restoring saved state for {}",
618 self.frames.len(),
619 frame.id().shape.blue()
620 );
621 frame.istate = iset;
622 }
623 self.frames.push(frame);
624 Ok(self)
625 }
626
627 pub fn field_index(&self, name: &str) -> Option<usize> {
639 let frame = self.frames.last()?;
640 match frame.shape.def {
641 Def::Struct(def) => def.fields.iter().position(|f| f.name == name),
642 Def::Enum(_) => {
643 let variant = frame.istate.variant.as_ref()?;
645 variant.data.fields.iter().position(|f| f.name == name)
646 }
647 _ => None,
648 }
649 }
650
651 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
663 let frame = self.frames.last().unwrap();
664 let shape = frame.shape;
665
666 if let Def::Enum(_) = shape.def {
668 if frame.istate.variant.is_none() {
669 return Err(ReflectError::OperationFailed {
670 shape,
671 operation: "tried to access a field by name but no variant was selected",
672 });
673 }
674 }
675
676 let index = self.field_index(name).ok_or(ReflectError::FieldError {
677 shape,
678 field_error: FieldError::NoSuchField,
679 })?;
680
681 self.field(index)
682 }
683
684 pub fn put<'val, T: Facet + 'val>(mut self, t: T) -> Result<Wip<'val>, ReflectError>
695 where
696 'a: 'val,
697 {
698 let Some(frame) = self.frames.last_mut() else {
699 return Err(ReflectError::OperationFailed {
700 shape: T::SHAPE,
701 operation: "tried to put a T but there was no frame to put T into",
702 });
703 };
704
705 if !frame.shape.is_type::<T>() {
707 if frame.shape.is_type::<Option<T>>() {
709 trace!("Putting into an option!");
710 let Def::Option(od) = frame.shape.def else {
711 unreachable!()
712 };
713
714 let src = PtrConst::new(&raw const t);
716 if frame.istate.fields.is_any_set() {
717 let data = unsafe { frame.data.assume_init() };
718 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
719 } else {
720 let data = frame.data;
721 unsafe { (od.vtable.init_some_fn)(data, src) };
722 }
723 unsafe {
724 frame.mark_fully_initialized();
725 }
726 let shape = frame.shape;
729 let index = frame.field_index_in_parent;
730
731 self.mark_field_as_initialized(shape, index)?;
733
734 trace!("[{}] Just put a {} value", self.frames.len(), shape.green());
735
736 return Ok(self);
737 }
738
739 return Err(ReflectError::WrongShape {
740 expected: frame.shape,
741 actual: T::SHAPE,
742 });
743 }
744
745 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
747 trace!(
748 "De-initializing partially initialized fields for {}",
749 frame.shape
750 );
751
752 match frame.shape.def {
753 Def::Struct(sd) => {
754 for (i, field) in sd.fields.iter().enumerate() {
755 if frame.istate.fields.has(i) {
756 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
757 unsafe {
758 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
759 drop_fn(PtrMut::new(field_ptr));
760 }
761 }
762 }
763 }
764 }
765 Def::Enum(_) => {
766 if let Some(variant) = &frame.istate.variant {
767 for (i, field) in variant.data.fields.iter().enumerate() {
768 if frame.istate.fields.has(i) {
769 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
770 unsafe {
771 let field_ptr =
772 frame.data.as_mut_byte_ptr().add(field.offset);
773 drop_fn(PtrMut::new(field_ptr));
774 }
775 }
776 }
777 }
778 }
779 }
780 _ => {
781 }
783 }
784
785 frame.istate.variant = None;
787 frame.istate.fields.clear();
788 }
789
790 unsafe {
791 frame.data.put(t);
792 frame.mark_fully_initialized();
793 }
794
795 let shape = frame.shape;
796 let index = frame.field_index_in_parent;
797
798 self.mark_field_as_initialized(shape, index)?;
800
801 trace!("[{}] Just put a {} value", self.frames.len(), shape.green());
802
803 Ok(self)
804 }
805
806 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
808 let Some(frame) = self.frames.last_mut() else {
809 return Err(ReflectError::OperationFailed {
810 shape: <()>::SHAPE,
811 operation: "tried to parse value but there was no frame",
812 });
813 };
814
815 let shape = frame.shape;
816 let index = frame.field_index_in_parent;
817
818 let Some(parse_fn) = frame.shape.vtable.parse else {
819 return Err(ReflectError::OperationFailed {
820 shape: frame.shape,
821 operation: "type does not implement Parse",
822 });
823 };
824 match unsafe { (parse_fn)(s, frame.data) } {
825 Ok(_res) => {
826 unsafe {
827 frame.mark_fully_initialized();
828 }
829
830 self.mark_field_as_initialized(shape, index)?;
832
833 Ok(self)
834 }
835 Err(_) => Err(ReflectError::OperationFailed {
836 shape,
837 operation: "parsing",
838 }),
839 }
840 }
841
842 pub fn put_default(mut self) -> Result<Self, ReflectError> {
844 let Some(frame) = self.frames.last_mut() else {
845 return Err(ReflectError::OperationFailed {
846 shape: <()>::SHAPE,
847 operation: "tried to put default value but there was no frame",
848 });
849 };
850
851 let vtable = frame.shape.vtable;
852
853 let Some(default_in_place) = vtable.default_in_place else {
854 return Err(ReflectError::OperationFailed {
855 shape: frame.shape,
856 operation: "type does not implement Default",
857 });
858 };
859 unsafe {
860 default_in_place(frame.data);
861 frame.mark_fully_initialized();
862 }
863
864 let shape = frame.shape;
865 let index = frame.field_index_in_parent;
866
867 self.mark_field_as_initialized(shape, index)?;
869
870 Ok(self)
871 }
872
873 fn mark_field_as_initialized(
875 &mut self,
876 shape: &'static Shape,
877 index: Option<usize>,
878 ) -> Result<(), ReflectError> {
879 if let Some(index) = index {
880 let parent_index = self.frames.len().saturating_sub(2);
881 let num_frames = self.frames.len();
882 let Some(parent) = self.frames.get_mut(parent_index) else {
883 return Err(ReflectError::OperationFailed {
884 shape,
885 operation: "was supposed to mark a field as initialized, but there was no parent frame",
886 });
887 };
888 let parent_shape = parent.shape;
889 trace!(
890 "[{}] {}.{} initialized with {}",
891 num_frames,
892 parent_shape.blue(),
893 index.yellow(),
894 shape.green()
895 );
896
897 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
898 return Err(ReflectError::OperationFailed {
899 shape,
900 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
901 });
902 }
903
904 if parent.istate.fields.has(index) {
905 return Err(ReflectError::OperationFailed {
906 shape,
907 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
908 });
909 }
910
911 parent.istate.fields.set(index);
912 }
913 Ok(())
914 }
915
916 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
918 let frame = self.frames.last().unwrap();
919 let shape = frame.shape;
920
921 match shape.def {
922 Def::List(list_def) => Ok(list_def.t()),
923 _ => Err(ReflectError::WasNotA {
924 expected: "list or array",
925 actual: shape,
926 }),
927 }
928 }
929
930 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
932 let frame = self.frames.last().unwrap();
933 let shape = frame.shape;
934
935 match shape.def {
936 Def::Map(map_def) => Ok(map_def.k),
937 _ => Err(ReflectError::WasNotA {
938 expected: "map",
939 actual: shape,
940 }),
941 }
942 }
943
944 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
946 let Some(frame) = self.frames.last_mut() else {
947 return Err(ReflectError::OperationFailed {
948 shape: <()>::SHAPE,
949 operation: "tried to create empty list but there was no frame",
950 });
951 };
952
953 if !matches!(frame.shape.def, Def::List(_)) {
954 return Err(ReflectError::WasNotA {
955 expected: "list or array",
956 actual: frame.shape,
957 });
958 }
959
960 let vtable = frame.shape.vtable;
961
962 let Some(default_in_place) = vtable.default_in_place else {
964 return Err(ReflectError::OperationFailed {
965 shape: frame.shape,
966 operation: "list type does not implement Default",
967 });
968 };
969
970 unsafe {
971 default_in_place(frame.data);
972 frame.mark_fully_initialized();
973 }
974
975 let shape = frame.shape;
976 let index = frame.field_index_in_parent;
977
978 self.mark_field_as_initialized(shape, index)?;
980
981 Ok(self)
982 }
983
984 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
986 let Some(frame) = self.frames.last_mut() else {
987 return Err(ReflectError::OperationFailed {
988 shape: <()>::SHAPE,
989 operation: "tried to create empty map but there was no frame",
990 });
991 };
992
993 if !matches!(frame.shape.def, Def::Map(_)) {
994 return Err(ReflectError::WasNotA {
995 expected: "map or hash map",
996 actual: frame.shape,
997 });
998 }
999
1000 let vtable = frame.shape.vtable;
1001
1002 let Some(default_in_place) = vtable.default_in_place else {
1004 return Err(ReflectError::OperationFailed {
1005 shape: frame.shape,
1006 operation: "map type does not implement Default",
1007 });
1008 };
1009
1010 unsafe {
1011 default_in_place(frame.data);
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 Ok(self)
1022 }
1023
1024 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1026 let Some(frame) = self.frames.last_mut() else {
1027 return Err(ReflectError::OperationFailed {
1028 shape: <()>::SHAPE,
1029 operation: "tried to begin pushback but there was no frame",
1030 });
1031 };
1032
1033 if !matches!(frame.shape.def, Def::List(_)) {
1034 return Err(ReflectError::WasNotA {
1035 expected: "list or array",
1036 actual: frame.shape,
1037 });
1038 }
1039
1040 let vtable = frame.shape.vtable;
1041
1042 if !frame.istate.fields.has(0) {
1044 let Some(default_in_place) = vtable.default_in_place else {
1045 return Err(ReflectError::OperationFailed {
1046 shape: frame.shape,
1047 operation: "list type does not implement Default",
1048 });
1049 };
1050
1051 unsafe {
1052 default_in_place(frame.data);
1053 frame.istate.fields.set(0);
1054 }
1055 }
1056
1057 Ok(self)
1058 }
1059
1060 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1062 let Some(frame) = self.frames.last_mut() else {
1063 return Err(ReflectError::OperationFailed {
1064 shape: <()>::SHAPE,
1065 operation: "tried to begin map insertion but there was no frame",
1066 });
1067 };
1068
1069 if !matches!(frame.shape.def, Def::Map(_)) {
1070 return Err(ReflectError::WasNotA {
1071 expected: "map or hash map",
1072 actual: frame.shape,
1073 });
1074 }
1075
1076 let vtable = frame.shape.vtable;
1077
1078 if !frame.istate.fields.has(0) {
1080 let Some(default_in_place) = vtable.default_in_place else {
1081 return Err(ReflectError::OperationFailed {
1082 shape: frame.shape,
1083 operation: "map type does not implement Default",
1084 });
1085 };
1086
1087 unsafe {
1088 default_in_place(frame.data);
1089 frame.istate.fields.set(0);
1090 }
1091 }
1092
1093 Ok(self)
1094 }
1095
1096 pub fn push(mut self) -> Result<Self, ReflectError> {
1101 let frame = self.frames.last().unwrap();
1103 let list_shape = frame.shape;
1104
1105 if !matches!(list_shape.def, Def::List(_)) {
1106 return Err(ReflectError::WasNotA {
1107 expected: "list or array",
1108 actual: list_shape,
1109 });
1110 }
1111
1112 if !frame.istate.fields.has(0) {
1114 self = self.begin_pushback()?;
1115 }
1116
1117 let element_shape = self.element_shape()?;
1119
1120 let element_data = element_shape.allocate();
1122
1123 let mut element_frame = Frame {
1125 data: element_data,
1126 shape: element_shape,
1127 field_index_in_parent: None, istate: IState::new(
1129 self.frames.len(),
1130 FrameMode::ListElement,
1131 FrameFlags::ALLOCATED,
1132 ),
1133 };
1134
1135 trace!(
1136 "[{}] Pushing element of type {} to list {}",
1137 self.frames.len(),
1138 element_shape.green(),
1139 list_shape.blue(),
1140 );
1141
1142 if let Some(iset) = self.istates.remove(&element_frame.id()) {
1143 trace!(
1144 "[{}] Restoring saved state for {}",
1145 self.frames.len(),
1146 element_frame.id().shape.blue()
1147 );
1148 element_frame.istate = iset;
1149 }
1150
1151 self.frames.push(element_frame);
1152 Ok(self)
1153 }
1154
1155 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1157 let frame = self.frames.last().unwrap();
1159 let option_shape = frame.shape;
1160
1161 if !matches!(option_shape.def, Def::Option(_)) {
1162 return Err(ReflectError::WasNotA {
1163 expected: "option",
1164 actual: option_shape,
1165 });
1166 }
1167
1168 let Def::Option(option_def) = option_shape.def else {
1170 unreachable!()
1171 };
1172
1173 let inner_shape = option_def.t();
1175
1176 let inner_data = inner_shape.allocate();
1178
1179 let mut inner_frame = Frame {
1181 data: inner_data,
1182 shape: inner_shape,
1183 field_index_in_parent: None,
1185 istate: IState::new(
1186 self.frames.len(),
1187 FrameMode::OptionSome,
1188 FrameFlags::ALLOCATED,
1190 ),
1191 };
1192
1193 trace!(
1194 "[{}] Pushing option frame for {}",
1195 self.frames.len(),
1196 option_shape.blue(),
1197 );
1198
1199 if let Some(iset) = self.istates.remove(&inner_frame.id()) {
1200 trace!(
1201 "[{}] Restoring saved state for {}",
1202 self.frames.len(),
1203 inner_frame.id().shape.blue()
1204 );
1205 inner_frame.istate = iset;
1206 }
1207
1208 self.frames.push(inner_frame);
1209 Ok(self)
1210 }
1211
1212 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1222 let Some(frame) = self.frames.last_mut() else {
1224 return Err(ReflectError::OperationFailed {
1225 shape: <()>::SHAPE,
1226 operation: "tried to pop_some_push_none but there was no frame",
1227 });
1228 };
1229
1230 if frame.istate.mode != FrameMode::OptionSome {
1232 return Err(ReflectError::OperationFailed {
1233 shape: frame.shape,
1234 operation: "pop_some_push_none called, but frame was not in Option mode",
1235 });
1236 }
1237
1238 if frame.is_fully_initialized() {
1240 return Err(ReflectError::OperationFailed {
1241 shape: frame.shape,
1242 operation: "option frame already initialized, cannot pop_some_push_none",
1243 });
1244 }
1245
1246 frame.dealloc_if_needed();
1247
1248 let _frame = self.frames.pop().expect("frame already checked");
1250
1251 let parent_frame = self
1253 .frames
1254 .last_mut()
1255 .ok_or(ReflectError::OperationFailed {
1256 shape: <()>::SHAPE,
1257 operation: "tried to pop_some_push_none but there was no parent frame",
1258 })?;
1259
1260 unsafe {
1262 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1263 default_fn(parent_frame.data);
1264 } else {
1265 return Err(ReflectError::OperationFailed {
1266 shape: parent_frame.shape,
1267 operation: "option type does not implement Default",
1268 });
1269 }
1270 parent_frame.mark_fully_initialized();
1271 }
1272
1273 let Def::Option(od) = parent_frame.shape.def else {
1274 return Err(ReflectError::OperationFailed {
1275 shape: parent_frame.shape,
1276 operation: "pop_some_push_none and the parent isn't of type Option???",
1277 });
1278 };
1279
1280 let data = parent_frame.data;
1282
1283 let mut frame = Frame {
1284 data,
1285 shape: od.t(),
1286 field_index_in_parent: Some(0),
1287 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1288 };
1289 unsafe {
1290 frame.mark_fully_initialized();
1291 }
1292
1293 self.frames.push(frame);
1294
1295 Ok(self)
1296 }
1297
1298 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1303 let frame = self.frames.last().unwrap();
1305 let map_shape = frame.shape;
1306
1307 if !matches!(map_shape.def, Def::Map(_)) {
1308 return Err(ReflectError::WasNotA {
1309 expected: "map or hash map",
1310 actual: map_shape,
1311 });
1312 }
1313
1314 if !frame.istate.fields.has(0) {
1316 self = self.begin_map_insert()?;
1317 }
1318
1319 let key_shape = self.key_shape()?;
1321
1322 let key_data = key_shape.allocate();
1324
1325 let mut key_frame = Frame {
1327 data: key_data,
1328 shape: key_shape,
1329 field_index_in_parent: None,
1330 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1331 };
1332
1333 trace!(
1334 "[{}] Pushing key of type {} for map {}",
1335 self.frames.len(),
1336 key_shape.green(),
1337 map_shape.blue(),
1338 );
1339
1340 if let Some(iset) = self.istates.remove(&key_frame.id()) {
1341 trace!(
1342 "[{}] Restoring saved state for {}",
1343 self.frames.len(),
1344 key_frame.id().shape.blue()
1345 );
1346 key_frame.istate = iset;
1347 }
1348
1349 self.frames.push(key_frame);
1350 Ok(self)
1351 }
1352
1353 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1358 trace!("Wants to push map value. Frames = ");
1359 for (i, f) in self.frames.iter().enumerate() {
1360 trace!("Frame {}: {:?}", i, f);
1361 }
1362
1363 if self.frames.len() < 2 {
1365 return Err(ReflectError::OperationFailed {
1366 shape: <()>::SHAPE,
1367 operation: "tried to push map value but there was no key frame",
1368 });
1369 }
1370
1371 let key_frame_index = self.frames.len() - 1;
1373 let key_frame = &self.frames[key_frame_index];
1374
1375 match key_frame.istate.mode {
1377 FrameMode::MapKey => {} _ => {
1379 return Err(ReflectError::OperationFailed {
1380 shape: key_frame.shape,
1381 operation: "current frame is not a map key",
1382 });
1383 }
1384 }
1385
1386 if !key_frame.is_fully_initialized() {
1388 return Err(ReflectError::OperationFailed {
1389 shape: key_frame.shape,
1390 operation: "map key is not fully initialized",
1391 });
1392 }
1393
1394 let map_frame_index = self.frames.len() - 2;
1396 let map_frame = &self.frames[map_frame_index];
1397 let map_shape = map_frame.shape;
1398
1399 let Def::Map(map_def) = map_shape.def else {
1400 return Err(ReflectError::WasNotA {
1401 expected: "map",
1402 actual: map_frame.shape,
1403 });
1404 };
1405
1406 let value_shape = map_def.v;
1407
1408 let value_data = value_shape.allocate();
1410
1411 let mut value_frame = Frame {
1413 data: value_data,
1414 shape: value_shape,
1415 field_index_in_parent: None,
1416 istate: IState::new(
1417 self.frames.len(),
1418 FrameMode::MapValue {
1419 index: key_frame_index,
1420 },
1421 FrameFlags::ALLOCATED,
1422 ),
1423 };
1424
1425 trace!(
1426 "[{}] Pushing value of type {} for map {} with key type {}",
1427 self.frames.len(),
1428 value_shape.green(),
1429 map_shape.blue(),
1430 key_frame.shape.yellow(),
1431 );
1432
1433 if let Some(iset) = self.istates.remove(&value_frame.id()) {
1434 trace!(
1435 "[{}] Restoring saved state for {}",
1436 self.frames.len(),
1437 value_frame.id().shape.blue()
1438 );
1439 value_frame.istate = iset;
1440 }
1441
1442 self.frames.push(value_frame);
1443 Ok(self)
1444 }
1445
1446 pub fn pop(mut self) -> Result<Self, ReflectError> {
1448 let Some(frame) = self.pop_inner() else {
1449 return Err(ReflectError::InvariantViolation {
1450 invariant: "No frame to pop",
1451 });
1452 };
1453 self.track(frame);
1454 Ok(self)
1455 }
1456
1457 fn pop_inner(&mut self) -> Option<Frame> {
1458 let mut frame = self.frames.pop()?;
1459 let frame_shape = frame.shape;
1460
1461 let init = frame.is_fully_initialized();
1462 trace!(
1463 "[{}] {} popped, {} initialized",
1464 self.frames.len(),
1465 frame_shape.blue(),
1466 if init {
1467 "✅ fully".green()
1468 } else {
1469 "🚧 partially".red()
1470 }
1471 );
1472 if init {
1473 if let Some(parent) = self.frames.last_mut() {
1474 if let Some(index) = frame.field_index_in_parent {
1475 parent.istate.fields.set(index);
1476 }
1477 }
1478 }
1479
1480 match frame.istate.mode {
1482 FrameMode::ListElement => {
1484 if frame.is_fully_initialized() {
1485 let frame_len = self.frames.len();
1488
1489 let parent_frame = self.frames.last_mut().unwrap();
1491 let parent_shape = parent_frame.shape;
1492
1493 match parent_shape.def {
1495 Def::List(_) => {
1496 if let Def::List(list_def) = parent_shape.def {
1498 let list_vtable = list_def.vtable;
1499 trace!(
1500 "[{}] Pushing element to list {}",
1501 frame_len,
1502 parent_shape.blue()
1503 );
1504 unsafe {
1505 (list_vtable.push)(
1507 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1508 PtrMut::new(frame.data.as_mut_byte_ptr()),
1509 );
1510 frame.mark_moved_out_of();
1511 }
1512 } else {
1513 panic!("parent frame is not a list type");
1514 }
1515 }
1516 _ => {
1517 panic!("Expected list or array, got {}", frame.shape);
1518 }
1519 }
1520 }
1521 }
1522
1523 FrameMode::MapValue {
1525 index: key_frame_index,
1526 } if frame.is_fully_initialized() => {
1527 let mut key_frame = self.frames.remove(key_frame_index);
1531
1532 if !key_frame.istate.fields.is_any_set() {
1534 panic!("key is not initialized when popping value frame");
1535 }
1536
1537 let frame_len = self.frames.len();
1539 let parent_frame = self.frames.last_mut().unwrap();
1540 let parent_shape = parent_frame.shape;
1541
1542 match parent_shape.def {
1544 Def::Map(_) => {
1545 if let Def::Map(map_def) = parent_shape.def {
1547 trace!(
1548 "[{}] Inserting key-value pair into map {}",
1549 frame_len,
1550 parent_shape.blue()
1551 );
1552 unsafe {
1553 (map_def.vtable.insert_fn)(
1555 parent_frame.data.assume_init(),
1556 key_frame.data.assume_init(),
1557 PtrMut::new(frame.data.as_mut_byte_ptr()),
1558 );
1559 key_frame.mark_moved_out_of();
1560 frame.mark_moved_out_of();
1561 }
1562 } else {
1563 panic!("parent frame is not a map type");
1564 }
1565 }
1566 _ => {
1567 panic!("Expected map or hash map, got {}", frame.shape);
1568 }
1569 }
1570 }
1571
1572 FrameMode::OptionSome => {
1574 if frame.is_fully_initialized() {
1575 trace!("Popping OptionSome (fully init'd)");
1576
1577 let frame_len = self.frames.len();
1579
1580 let parent_frame = self.frames.last_mut().unwrap();
1582 let parent_shape = parent_frame.shape;
1583
1584 match parent_shape.def {
1586 Def::Option(option_def) => {
1587 trace!(
1588 "[{}] Setting Some value in option {}",
1589 frame_len,
1590 parent_shape.blue()
1591 );
1592 unsafe {
1593 (option_def.vtable.init_some_fn)(
1595 parent_frame.data,
1596 PtrConst::new(frame.data.as_byte_ptr()),
1597 );
1598 trace!("Marking parent frame as fully initialized");
1599 parent_frame.mark_fully_initialized();
1600
1601 frame.mark_moved_out_of();
1602 }
1603 }
1604 _ => {
1605 panic!(
1606 "Expected parent frame to be an option type, got {}",
1607 frame.shape
1608 );
1609 }
1610 }
1611 } else {
1612 trace!("Popping OptionSome (not fully init'd)");
1613 }
1614 }
1615
1616 FrameMode::MapKey => {}
1619
1620 FrameMode::Normal => {}
1622
1623 _ => {}
1625 }
1626
1627 Some(frame)
1628 }
1629
1630 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
1634 match frame.shape.def {
1635 Def::Struct(sd) => {
1636 for f in sd.fields {
1637 let id = ValueId {
1638 shape: f.shape(),
1639 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1640 };
1641 if let Some(istate) = self.istates.remove(&id) {
1642 let frame = Frame::recompose(id, istate);
1643 self.evict_tree(frame);
1644 } else {
1645 trace!("No istate found for field {}", f.name);
1646 }
1647 }
1648 }
1649 Def::Enum(_ed) => {
1650 if let Some(variant) = &frame.istate.variant {
1652 trace!(
1653 "Evicting enum {} variant '{}' fields",
1654 frame.shape.blue(),
1655 variant.name.yellow()
1656 );
1657 for field in variant.data.fields {
1659 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1661 let field_shape = field.shape();
1662 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1663
1664 if let Some(field_istate) = self.istates.remove(&field_id) {
1666 trace!(
1667 "Evicting field '{}' (shape {}) of enum variant '{}'",
1668 field.name.bright_blue(),
1669 field_shape.green(),
1670 variant.name.yellow()
1671 );
1672 let field_frame = Frame::recompose(field_id, field_istate);
1674 self.evict_tree(field_frame);
1676 } else {
1677 trace!(
1678 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1679 field.name.red(),
1680 field_shape.red(),
1681 variant.name.yellow()
1682 );
1683 }
1684 }
1685 } else {
1686 trace!(
1688 "Enum {} has no variant selected, no fields to evict.",
1689 frame.shape.blue()
1690 );
1691 }
1692 }
1693 _ => {}
1694 }
1695 frame
1696 }
1697}
1698
1699impl Drop for Wip<'_> {
1700 fn drop(&mut self) {
1701 while let Some(frame) = self.frames.pop() {
1702 self.track(frame);
1703 }
1704 trace!("🧹 Whole WIP is dropping",);
1705
1706 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
1707 trace!("No root found, we probably built already");
1708 return;
1709 };
1710
1711 let root_id = *root_id;
1712 let root_istate = self.istates.remove(&root_id).unwrap();
1713 let root = Frame::recompose(root_id, root_istate);
1714 let mut to_clean = vec![root];
1715
1716 let mut _root_guard: Option<Guard> = None;
1717
1718 while let Some(mut frame) = to_clean.pop() {
1719 trace!(
1720 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
1721 frame.shape.blue(),
1722 frame.data.as_byte_ptr(),
1723 frame.istate.flags.bright_magenta(),
1724 frame.istate.mode.yellow(),
1725 if frame.is_fully_initialized() {
1726 "✅".green()
1727 } else {
1728 "❌".red()
1729 }
1730 );
1731
1732 if frame.istate.flags.contains(FrameFlags::MOVED) {
1733 trace!(
1734 "{}",
1735 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
1736 );
1737 continue;
1738 }
1739
1740 match frame.shape.def {
1741 Def::Struct(sd) => {
1742 if frame.is_fully_initialized() {
1743 trace!(
1744 "Dropping fully initialized struct: {} at {:p}",
1745 frame.shape.green(),
1746 frame.data.as_byte_ptr()
1747 );
1748 let frame = self.evict_tree(frame);
1749 unsafe { frame.drop_and_dealloc_if_needed() };
1750 } else {
1751 let num_fields = sd.fields.len();
1752 trace!(
1753 "De-initializing struct {} at {:p} field-by-field ({} fields)",
1754 frame.shape.yellow(),
1755 frame.data.as_byte_ptr(),
1756 num_fields.to_string().bright_cyan()
1757 );
1758 for i in 0..num_fields {
1759 if frame.istate.fields.has(i) {
1760 let field = sd.fields[i];
1761 let field_shape = field.shape();
1762 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
1763 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1764 trace!(
1765 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
1766 i.to_string().bright_cyan(),
1767 field.name.bright_blue(),
1768 frame.shape.blue(),
1769 field_shape.green(),
1770 field_ptr.as_byte_ptr()
1771 );
1772 let istate = self.istates.remove(&field_id).unwrap();
1773 let field_frame = Frame::recompose(field_id, istate);
1774 to_clean.push(field_frame);
1775 } else {
1776 trace!(
1777 "Field #{} '{}' of {} was NOT initialized, skipping",
1778 i.to_string().bright_cyan(),
1779 sd.fields[i].name.bright_red(),
1780 frame.shape.red()
1781 );
1782 }
1783 }
1784
1785 if frame.istate.mode == FrameMode::Root {
1787 _root_guard = Some(Guard {
1788 ptr: frame.data.as_mut_byte_ptr(),
1789 layout: frame.shape.layout,
1790 });
1791 }
1792 }
1793 }
1794 Def::Enum(_ed) => {
1795 trace!(
1796 "{}",
1797 format!(
1798 "TODO: handle enum deallocation for {} at {:p}",
1799 frame.shape.yellow(),
1800 frame.data.as_byte_ptr()
1801 )
1802 .magenta()
1803 );
1804
1805 if frame.istate.mode == FrameMode::Root {
1807 _root_guard = Some(Guard {
1808 ptr: frame.data.as_mut_byte_ptr(),
1809 layout: frame.shape.layout,
1810 });
1811 }
1812 }
1813 Def::Array(_)
1814 | Def::Slice(_)
1815 | Def::List(_)
1816 | Def::Map(_)
1817 | Def::SmartPointer(_)
1818 | Def::Scalar(_)
1819 | Def::Option(_) => {
1820 trace!(
1821 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
1822 frame.shape.cyan(),
1823 frame.shape.def,
1824 frame.istate.mode.yellow(),
1825 frame.data.as_byte_ptr(),
1826 );
1827
1828 if frame.is_fully_initialized() {
1829 unsafe { frame.drop_and_dealloc_if_needed() }
1830 } else {
1831 frame.dealloc_if_needed();
1832 }
1833 }
1834 _ => {}
1835 }
1836 }
1837
1838 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
1840 for frame_id in all_ids.drain(..) {
1841 let frame_istate = self.istates.remove(&frame_id).unwrap();
1842
1843 trace!(
1844 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
1845 frame_id.shape.cyan(),
1846 frame_id.ptr,
1847 frame_istate.mode.yellow()
1848 );
1849 let mut frame = Frame::recompose(frame_id, frame_istate);
1850
1851 if frame.is_fully_initialized() {
1852 trace!("It's fully initialized, we can drop it");
1853 unsafe { frame.drop_and_dealloc_if_needed() };
1854 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
1855 trace!("Not initialized but allocated, let's free it");
1856 frame.dealloc_if_needed();
1857 }
1858 }
1859 }
1860}