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<*mut &'a ()>,
287}
288
289impl<'a> Wip<'a> {
290 pub fn put_peek(self, peek: crate::Peek<'a>) -> Result<Wip<'a>, ReflectError> {
292 self.put_shape(peek.data, peek.shape)
293 }
294
295 pub fn frames_count(&self) -> usize {
297 self.frames.len()
298 }
299
300 pub fn alloc_shape(shape: &'static Shape) -> Self {
302 let data = shape.allocate();
303 Self {
304 frames: alloc::vec![Frame {
305 data,
306 shape,
307 field_index_in_parent: None,
308 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
309 }],
310 istates: Default::default(),
311 phantom: PhantomData,
312 }
313 }
314
315 pub fn alloc<S: Facet<'a>>() -> Self {
317 Self::alloc_shape(S::SHAPE)
318 }
319
320 fn track(&mut self, frame: Frame) {
321 if !frame.istate.flags.contains(FrameFlags::MOVED) {
327 self.istates.insert(frame.id(), frame.istate);
328 }
329 }
330
331 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame) {
332 frame.dealloc_if_needed();
333 ISet::clear(&mut frame.istate.fields);
334 frame.istate.variant = None;
335 frame.istate.flags.insert(FrameFlags::MOVED);
336 self.istates.remove(&frame.id());
339 }
340
341 pub fn shape(&self) -> &'static Shape {
343 self.frames.last().expect("must have frames left").shape
344 }
345
346 pub fn in_option(&self) -> bool {
348 let Some(frame) = self.frames.last() else {
349 return false;
350 };
351 matches!(frame.istate.mode, FrameMode::OptionSome)
352 }
353
354 pub fn mode(&self) -> FrameMode {
356 self.frames.last().unwrap().istate.mode
357 }
358
359 pub fn build(mut self) -> Result<HeapValue<'a>, ReflectError> {
361 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
362
363 while let Some(frame) = self.pop_inner() {
365 self.track(frame);
366 }
367
368 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
370 debug!("No root found, possibly already built or empty WIP");
371 return Err(ReflectError::OperationFailed {
372 shape: <()>::SHAPE,
373 operation: "tried to build a value but there was no root frame tracked",
374 });
375 };
376
377 let root_id = *root_id;
378 let root_istate = self
381 .istates
382 .remove(&root_id)
383 .expect("Root ID found but not present in istates, this is a bug"); let root_frame = Frame::recompose(root_id, root_istate);
386 let root_shape = root_frame.shape;
387 let root_data_ptr = root_frame.data; let guard = Guard {
394 ptr: root_data_ptr.as_mut_byte_ptr(),
395 layout: root_shape.layout,
396 };
397
398 let mut to_check = alloc::vec![root_frame];
400
401 while let Some(frame) = to_check.pop() {
403 trace!(
404 "Checking frame: shape={} at {:p}, flags={:?}, mode={:?}",
405 frame.shape.blue(),
406 frame.data.as_byte_ptr(),
407 frame.istate.flags.bright_magenta(),
408 frame.istate.mode,
409 );
410
411 if frame.istate.flags.contains(FrameFlags::MOVED) {
413 trace!(
414 "{}",
415 "Frame was moved out of, skipping initialization check".yellow()
416 );
417 continue;
418 }
419
420 match frame.shape.def {
422 Def::Struct(sd) => {
423 if !frame.is_fully_initialized() {
424 for i in 0..sd.fields.len() {
426 if !frame.istate.fields.has(i) {
427 let field = &sd.fields[i];
428 return Err(ReflectError::UninitializedField {
429 shape: frame.shape,
430 field_name: field.name,
431 });
432 }
433 }
434 unreachable!(
436 "Enum variant not fully initialized but couldn't find which field"
437 );
438 }
439
440 #[allow(clippy::unused_enumerate_index)]
442 for (_i, field) in sd.fields.iter().enumerate() {
443 let field_shape = field.shape();
444 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
445 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
446
447 if let Some(field_istate) = self.istates.remove(&field_id) {
448 debug!(
449 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
450 _i.to_string().bright_cyan(),
451 field.name.bright_blue(),
452 frame.shape.blue(),
453 field_shape.green(),
454 field_ptr.as_byte_ptr()
455 );
456 let field_frame = Frame::recompose(field_id, field_istate);
457 to_check.push(field_frame);
458 }
459 }
460 }
461 Def::Enum(_ed) => {
462 if let Some(variant) = &frame.istate.variant {
463 if !frame.istate.fields.are_all_set(variant.data.fields.len()) {
464 for (i, field) in variant.data.fields.iter().enumerate() {
466 if !frame.istate.fields.has(i) {
467 return Err(ReflectError::UninitializedEnumField {
468 shape: frame.shape,
469 variant_name: variant.name,
470 field_name: field.name,
471 });
472 }
473 }
474 unreachable!(
476 "Enum variant not fully initialized but couldn't find which field"
477 );
478 }
479
480 #[allow(clippy::unused_enumerate_index)]
482 for (_i, field) in variant.data.fields.iter().enumerate() {
483 let field_shape = field.shape();
484 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
488 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
489
490 if let Some(field_istate) = self.istates.remove(&field_id) {
491 debug!(
492 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
493 _i.to_string().bright_cyan(),
494 field.name.bright_blue(),
495 variant.name.yellow(),
496 frame.shape.blue(),
497 field_shape.green(),
498 field_ptr.as_byte_ptr()
499 );
500 let field_frame = Frame::recompose(field_id, field_istate);
501 to_check.push(field_frame);
502 }
503 }
504 } else {
505 return Err(ReflectError::NoVariantSelected { shape: frame.shape });
507 }
508 }
509 Def::List(_)
513 | Def::Map(_)
514 | Def::Option(_)
515 | Def::Scalar(_)
516 | Def::FunctionPointer(_)
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<T: Facet<'a>>(self, t: T) -> Result<Wip<'a>, ReflectError> {
749 let shape = T::SHAPE;
750 let ptr_const = PtrConst::new(&t as *const T as *const u8);
751 let res = self.put_shape(ptr_const, shape);
752 core::mem::forget(t); res
754 }
755
756 pub fn current_is_type<T: Facet<'static>>(&self) -> bool {
758 self.frames
759 .last()
760 .is_some_and(|frame| frame.shape == T::SHAPE)
761 }
762
763 pub fn put_shape(
765 mut self,
766 src: PtrConst<'a>,
767 src_shape: &'static Shape,
768 ) -> Result<Wip<'a>, ReflectError> {
769 let Some(frame) = self.frames.last_mut() else {
770 return Err(ReflectError::OperationFailed {
771 shape: src_shape,
772 operation: "tried to put a value but there was no frame to put into",
773 });
774 };
775
776 if frame.shape != src_shape {
778 trace!(
779 "Trying to put a {} into a {}",
780 src_shape.yellow(),
781 frame.shape.magenta()
782 );
783
784 if let Some(try_from) = frame.shape.vtable.try_from {
786 match unsafe { try_from(src, src_shape, frame.data) } {
787 Ok(_) => {
788 unsafe {
789 frame.mark_fully_initialized();
790 }
791
792 let shape = frame.shape;
793 let index = frame.field_index_in_parent;
794
795 self.mark_field_as_initialized(shape, index)?;
797
798 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
799
800 return Ok(self);
801 }
802 Err(e) => {
803 return Err(ReflectError::TryFromError {
804 inner: e,
805 src_shape,
806 dst_shape: frame.shape,
807 });
808 }
809 }
810 }
811
812 if let Def::Option(od) = frame.shape.def {
815 if od.t() == src_shape {
817 debug!("Putting into an Option<T>!");
818 if frame.istate.fields.is_any_set() {
819 let data = unsafe { frame.data.assume_init() };
820 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
821 } else {
822 let data = frame.data;
823 unsafe { (od.vtable.init_some_fn)(data, src) };
824 }
825 unsafe {
826 frame.mark_fully_initialized();
827 }
828
829 let shape = frame.shape;
830 let index = frame.field_index_in_parent;
831
832 self.mark_field_as_initialized(shape, index)?;
834
835 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
836
837 return Ok(self);
838 }
839 }
840
841 if let Def::Struct(sd) = frame.shape.def {
845 for (i, field) in sd.fields.iter().enumerate() {
847 if !frame.istate.fields.has(i) && field.shape() == src_shape {
848 debug!(
849 "Found uninitialized field {} with matching type {}",
850 i.to_string().blue(),
851 src_shape.green()
852 );
853
854 unsafe {
856 let field_data = frame.data.field_uninit_at(field.offset);
857 field_data.copy_from(src, field.shape());
858 frame.istate.fields.set(i);
859 }
860
861 let shape = frame.shape;
862 let index = frame.field_index_in_parent;
863
864 if frame.is_fully_initialized() {
866 self.mark_field_as_initialized(shape, index)?;
867 }
868
869 debug!(
870 "[{}] Put a {} value into field {} of {}",
871 self.frames.len(),
872 src_shape.green(),
873 i.to_string().blue(),
874 shape.green()
875 );
876
877 return Ok(self);
878 }
879 }
880 }
881
882 if let Def::Enum(_) = frame.shape.def {
885 if let Some(variant) = &frame.istate.variant {
887 for (i, field) in variant.data.fields.iter().enumerate() {
889 if !frame.istate.fields.has(i) && field.shape() == src_shape {
890 debug!(
891 "Found uninitialized field {} in enum variant '{}' with matching type {}",
892 i.to_string().blue(),
893 variant.name.bright_yellow(),
894 src_shape.green()
895 );
896
897 unsafe {
899 let field_data = frame.data.field_uninit_at(field.offset);
900 field_data.copy_from(src, field.shape());
901 frame.istate.fields.set(i);
902 }
903
904 let shape = frame.shape;
905 let index = frame.field_index_in_parent;
906
907 #[allow(unused)]
908 let variant_name = variant.name;
909
910 if frame.is_fully_initialized() {
912 self.mark_field_as_initialized(shape, index)?;
913 }
914
915 debug!(
916 "[{}] Put a {} value into field {} of variant '{}' in enum {}",
917 self.frames.len(),
918 src_shape.green(),
919 i.to_string().blue(),
920 variant_name.bright_yellow(),
921 shape.green()
922 );
923
924 return Ok(self);
925 }
926 }
927 }
928 }
929
930 return Err(ReflectError::WrongShape {
931 expected: frame.shape,
932 actual: src_shape,
933 });
934 }
935
936 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
938 debug!(
939 "De-initializing partially initialized fields for {}",
940 frame.shape
941 );
942
943 match frame.shape.def {
944 Def::Struct(sd) => {
945 for (i, field) in sd.fields.iter().enumerate() {
946 if frame.istate.fields.has(i) {
947 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
948 unsafe {
949 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
950 drop_fn(PtrMut::new(field_ptr));
951 }
952 }
953 }
954 }
955 }
956 Def::Enum(_) => {
957 if let Some(variant) = &frame.istate.variant {
958 for (i, field) in variant.data.fields.iter().enumerate() {
959 if frame.istate.fields.has(i) {
960 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
961 unsafe {
962 let field_ptr =
963 frame.data.as_mut_byte_ptr().add(field.offset);
964 drop_fn(PtrMut::new(field_ptr));
965 }
966 }
967 }
968 }
969 }
970 }
971 _ => {
972 }
974 }
975
976 frame.istate.variant = None;
978 ISet::clear(&mut frame.istate.fields);
979 }
980
981 unsafe {
982 frame.data.copy_from(src, frame.shape);
984 frame.mark_fully_initialized();
985 }
986
987 let shape = frame.shape;
988 let index = frame.field_index_in_parent;
989
990 self.mark_field_as_initialized(shape, index)?;
992
993 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
994
995 Ok(self)
996 }
997
998 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
1000 let Some(frame) = self.frames.last_mut() else {
1001 return Err(ReflectError::OperationFailed {
1002 shape: <()>::SHAPE,
1003 operation: "tried to parse value but there was no frame",
1004 });
1005 };
1006
1007 let shape = frame.shape;
1008 let index = frame.field_index_in_parent;
1009
1010 let Some(parse_fn) = frame.shape.vtable.parse else {
1011 return Err(ReflectError::OperationFailed {
1012 shape: frame.shape,
1013 operation: "type does not implement Parse",
1014 });
1015 };
1016 match unsafe { (parse_fn)(s, frame.data) } {
1017 Ok(_res) => {
1018 unsafe {
1019 frame.mark_fully_initialized();
1020 }
1021
1022 self.mark_field_as_initialized(shape, index)?;
1024
1025 Ok(self)
1026 }
1027 Err(_) => Err(ReflectError::OperationFailed {
1028 shape,
1029 operation: "parsing",
1030 }),
1031 }
1032 }
1033
1034 pub fn put_from_fn(mut self, default_in_place: DefaultInPlaceFn) -> Result<Self, ReflectError> {
1036 let Some(frame) = self.frames.last_mut() else {
1037 return Err(ReflectError::OperationFailed {
1038 shape: <()>::SHAPE,
1039 operation: "tried to put value from fn but there was no frame",
1040 });
1041 };
1042
1043 unsafe {
1044 default_in_place(frame.data);
1045 frame.mark_fully_initialized();
1046 }
1047
1048 let shape = frame.shape;
1049 let index = frame.field_index_in_parent;
1050
1051 self.mark_field_as_initialized(shape, index)?;
1053
1054 Ok(self)
1055 }
1056
1057 pub fn put_default(self) -> Result<Self, ReflectError> {
1059 let Some(frame) = self.frames.last() else {
1060 return Err(ReflectError::OperationFailed {
1061 shape: <()>::SHAPE,
1062 operation: "tried to put default value but there was no frame",
1063 });
1064 };
1065
1066 let vtable = frame.shape.vtable;
1067 let Some(default_in_place) = vtable.default_in_place else {
1068 return Err(ReflectError::OperationFailed {
1069 shape: frame.shape,
1070 operation: "type does not implement Default",
1071 });
1072 };
1073
1074 self.put_from_fn(default_in_place)
1075 }
1076
1077 fn mark_field_as_initialized(
1079 &mut self,
1080 shape: &'static Shape,
1081 index: Option<usize>,
1082 ) -> Result<(), ReflectError> {
1083 if let Some(index) = index {
1084 let parent_index = self.frames.len().saturating_sub(2);
1085 #[cfg(feature = "log")]
1086 let num_frames = self.frames.len();
1087 let Some(parent) = self.frames.get_mut(parent_index) else {
1088 return Err(ReflectError::OperationFailed {
1089 shape,
1090 operation: "was supposed to mark a field as initialized, but there was no parent frame",
1091 });
1092 };
1093 #[cfg(feature = "log")]
1094 let parent_shape = parent.shape;
1095 trace!(
1096 "[{}] {}.{} initialized with {}",
1097 num_frames,
1098 parent_shape.blue(),
1099 index.yellow(),
1100 shape.green()
1101 );
1102
1103 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
1104 return Err(ReflectError::OperationFailed {
1105 shape,
1106 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
1107 });
1108 }
1109
1110 if parent.istate.fields.has(index) {
1111 return Err(ReflectError::OperationFailed {
1112 shape,
1113 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
1114 });
1115 }
1116
1117 parent.istate.fields.set(index);
1118 }
1119 Ok(())
1120 }
1121
1122 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
1124 let frame = self.frames.last().unwrap();
1125 let shape = frame.shape;
1126
1127 match shape.def {
1128 Def::List(list_def) => Ok(list_def.t()),
1129 _ => Err(ReflectError::WasNotA {
1130 expected: "list or array",
1131 actual: shape,
1132 }),
1133 }
1134 }
1135
1136 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
1138 let frame = self.frames.last().unwrap();
1139 let shape = frame.shape;
1140
1141 match shape.def {
1142 Def::Map(map_def) => Ok(map_def.k),
1143 _ => Err(ReflectError::WasNotA {
1144 expected: "map",
1145 actual: shape,
1146 }),
1147 }
1148 }
1149
1150 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
1152 let Some(frame) = self.frames.last_mut() else {
1153 return Err(ReflectError::OperationFailed {
1154 shape: <()>::SHAPE,
1155 operation: "tried to create empty list but there was no frame",
1156 });
1157 };
1158
1159 if !matches!(frame.shape.def, Def::List(_)) {
1160 return Err(ReflectError::WasNotA {
1161 expected: "list or array",
1162 actual: frame.shape,
1163 });
1164 }
1165
1166 let vtable = frame.shape.vtable;
1167
1168 let Some(default_in_place) = vtable.default_in_place else {
1170 return Err(ReflectError::OperationFailed {
1171 shape: frame.shape,
1172 operation: "list type does not implement Default",
1173 });
1174 };
1175
1176 unsafe {
1177 default_in_place(frame.data);
1178 frame.mark_fully_initialized();
1179 }
1180
1181 let shape = frame.shape;
1182 let index = frame.field_index_in_parent;
1183
1184 self.mark_field_as_initialized(shape, index)?;
1186
1187 Ok(self)
1188 }
1189
1190 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1192 let Some(frame) = self.frames.last_mut() else {
1193 return Err(ReflectError::OperationFailed {
1194 shape: <()>::SHAPE,
1195 operation: "tried to create empty map but there was no frame",
1196 });
1197 };
1198
1199 if !matches!(frame.shape.def, Def::Map(_)) {
1200 return Err(ReflectError::WasNotA {
1201 expected: "map or hash map",
1202 actual: frame.shape,
1203 });
1204 }
1205
1206 let vtable = frame.shape.vtable;
1207
1208 let Some(default_in_place) = vtable.default_in_place else {
1210 return Err(ReflectError::OperationFailed {
1211 shape: frame.shape,
1212 operation: "map type does not implement Default",
1213 });
1214 };
1215
1216 unsafe {
1217 default_in_place(frame.data);
1218 frame.mark_fully_initialized();
1219 }
1220
1221 let shape = frame.shape;
1222 let index = frame.field_index_in_parent;
1223
1224 self.mark_field_as_initialized(shape, index)?;
1226
1227 Ok(self)
1228 }
1229
1230 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1232 let Some(frame) = self.frames.last_mut() else {
1233 return Err(ReflectError::OperationFailed {
1234 shape: <()>::SHAPE,
1235 operation: "tried to begin pushback but there was no frame",
1236 });
1237 };
1238
1239 if !matches!(frame.shape.def, Def::List(_)) {
1240 return Err(ReflectError::WasNotA {
1241 expected: "list or array",
1242 actual: frame.shape,
1243 });
1244 }
1245
1246 let vtable = frame.shape.vtable;
1247
1248 if !frame.istate.fields.has(0) {
1250 let Some(default_in_place) = vtable.default_in_place else {
1251 return Err(ReflectError::OperationFailed {
1252 shape: frame.shape,
1253 operation: "list type does not implement Default",
1254 });
1255 };
1256
1257 unsafe {
1258 default_in_place(frame.data);
1259 frame.istate.fields.set(0);
1260 }
1261 }
1262
1263 Ok(self)
1264 }
1265
1266 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1268 let Some(frame) = self.frames.last_mut() else {
1269 return Err(ReflectError::OperationFailed {
1270 shape: <()>::SHAPE,
1271 operation: "tried to begin map insertion but there was no frame",
1272 });
1273 };
1274
1275 if !matches!(frame.shape.def, Def::Map(_)) {
1276 return Err(ReflectError::WasNotA {
1277 expected: "map or hash map",
1278 actual: frame.shape,
1279 });
1280 }
1281
1282 let vtable = frame.shape.vtable;
1283
1284 if !frame.istate.fields.has(0) {
1286 let Some(default_in_place) = vtable.default_in_place else {
1287 return Err(ReflectError::OperationFailed {
1288 shape: frame.shape,
1289 operation: "map type does not implement Default",
1290 });
1291 };
1292
1293 unsafe {
1294 default_in_place(frame.data);
1295 frame.istate.fields.set(0);
1296 }
1297 }
1298
1299 Ok(self)
1300 }
1301
1302 pub fn push(mut self) -> Result<Self, ReflectError> {
1307 let frame = self.frames.last().unwrap();
1309 let list_shape = frame.shape;
1310
1311 if !matches!(list_shape.def, Def::List(_)) {
1312 return Err(ReflectError::WasNotA {
1313 expected: "list or array",
1314 actual: list_shape,
1315 });
1316 }
1317
1318 if !frame.istate.fields.has(0) {
1320 self = self.begin_pushback()?;
1321 }
1322
1323 let element_shape = self.element_shape()?;
1325
1326 let element_data = element_shape.allocate();
1328
1329 let element_frame = Frame {
1331 data: element_data,
1332 shape: element_shape,
1333 field_index_in_parent: None, istate: IState::new(
1335 self.frames.len(),
1336 FrameMode::ListElement,
1337 FrameFlags::ALLOCATED,
1338 ),
1339 };
1340
1341 trace!(
1342 "[{}] Pushing element of type {} to list {}",
1343 self.frames.len(),
1344 element_shape.green(),
1345 list_shape.blue(),
1346 );
1347
1348 self.frames.push(element_frame);
1349 Ok(self)
1350 }
1351
1352 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1354 let frame = self.frames.last().unwrap();
1356 let option_shape = frame.shape;
1357
1358 let Def::Option(option_def) = option_shape.def else {
1360 return Err(ReflectError::WasNotA {
1361 expected: "option",
1362 actual: option_shape,
1363 });
1364 };
1365
1366 let inner_shape = option_def.t();
1368
1369 let inner_data = inner_shape.allocate();
1371
1372 let inner_frame = Frame {
1374 data: inner_data,
1375 shape: inner_shape,
1376 field_index_in_parent: None,
1378 istate: IState::new(
1379 self.frames.len(),
1380 FrameMode::OptionSome,
1381 FrameFlags::ALLOCATED,
1383 ),
1384 };
1385
1386 trace!(
1387 "[{}] Pushing option frame for {}",
1388 self.frames.len(),
1389 option_shape.blue(),
1390 );
1391
1392 self.frames.push(inner_frame);
1393 Ok(self)
1394 }
1395
1396 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1406 let Some(frame) = self.frames.last_mut() else {
1408 return Err(ReflectError::OperationFailed {
1409 shape: <()>::SHAPE,
1410 operation: "tried to pop_some_push_none but there was no frame",
1411 });
1412 };
1413
1414 if frame.istate.mode != FrameMode::OptionSome {
1416 return Err(ReflectError::OperationFailed {
1417 shape: frame.shape,
1418 operation: "pop_some_push_none called, but frame was not in Option mode",
1419 });
1420 }
1421
1422 if frame.is_fully_initialized() {
1424 return Err(ReflectError::OperationFailed {
1425 shape: frame.shape,
1426 operation: "option frame already initialized, cannot pop_some_push_none",
1427 });
1428 }
1429
1430 frame.dealloc_if_needed();
1431
1432 let _frame = self.frames.pop().expect("frame already checked");
1434
1435 let parent_frame = self
1437 .frames
1438 .last_mut()
1439 .ok_or(ReflectError::OperationFailed {
1440 shape: <()>::SHAPE,
1441 operation: "tried to pop_some_push_none but there was no parent frame",
1442 })?;
1443
1444 unsafe {
1446 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1447 default_fn(parent_frame.data);
1448 } else {
1449 return Err(ReflectError::OperationFailed {
1450 shape: parent_frame.shape,
1451 operation: "option type does not implement Default",
1452 });
1453 }
1454 parent_frame.mark_fully_initialized();
1455 }
1456
1457 let Def::Option(od) = parent_frame.shape.def else {
1458 return Err(ReflectError::OperationFailed {
1459 shape: parent_frame.shape,
1460 operation: "pop_some_push_none and the parent isn't of type Option???",
1461 });
1462 };
1463
1464 let data = parent_frame.data;
1466
1467 let mut frame = Frame {
1468 data,
1469 shape: od.t(),
1470 field_index_in_parent: Some(0),
1471 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1472 };
1473 unsafe {
1474 frame.mark_fully_initialized();
1475 }
1476
1477 self.frames.push(frame);
1478
1479 Ok(self)
1480 }
1481
1482 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1487 let frame = self.frames.last().unwrap();
1489 let map_shape = frame.shape;
1490
1491 if !matches!(map_shape.def, Def::Map(_)) {
1492 return Err(ReflectError::WasNotA {
1493 expected: "map or hash map",
1494 actual: map_shape,
1495 });
1496 }
1497
1498 if !frame.istate.fields.has(0) {
1500 self = self.begin_map_insert()?;
1501 }
1502
1503 let key_shape = self.key_shape()?;
1505
1506 let key_data = key_shape.allocate();
1508
1509 let key_frame = Frame {
1511 data: key_data,
1512 shape: key_shape,
1513 field_index_in_parent: None,
1514 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1515 };
1516
1517 trace!(
1518 "[{}] Pushing key of type {} for map {}",
1519 self.frames.len(),
1520 key_shape.green(),
1521 map_shape.blue(),
1522 );
1523
1524 self.frames.push(key_frame);
1525 Ok(self)
1526 }
1527
1528 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1533 trace!("Wants to push map value. Frames = ");
1534 #[cfg(feature = "log")]
1535 for (i, f) in self.frames.iter().enumerate() {
1536 trace!("Frame {}: {:?}", i, f);
1537 }
1538
1539 if self.frames.len() < 2 {
1541 return Err(ReflectError::OperationFailed {
1542 shape: <()>::SHAPE,
1543 operation: "tried to push map value but there was no key frame",
1544 });
1545 }
1546
1547 let key_frame_index = self.frames.len() - 1;
1549 let key_frame = &self.frames[key_frame_index];
1550
1551 match key_frame.istate.mode {
1553 FrameMode::MapKey => {} _ => {
1555 return Err(ReflectError::OperationFailed {
1556 shape: key_frame.shape,
1557 operation: "current frame is not a map key",
1558 });
1559 }
1560 }
1561
1562 if !key_frame.is_fully_initialized() {
1564 return Err(ReflectError::OperationFailed {
1565 shape: key_frame.shape,
1566 operation: "map key is not fully initialized",
1567 });
1568 }
1569
1570 let map_frame_index = self.frames.len() - 2;
1572 let map_frame = &self.frames[map_frame_index];
1573 let map_shape = map_frame.shape;
1574
1575 let Def::Map(map_def) = map_shape.def else {
1576 return Err(ReflectError::WasNotA {
1577 expected: "map",
1578 actual: map_frame.shape,
1579 });
1580 };
1581
1582 let value_shape = map_def.v;
1583
1584 let value_data = value_shape.allocate();
1586
1587 let value_frame = Frame {
1589 data: value_data,
1590 shape: value_shape,
1591 field_index_in_parent: None,
1592 istate: IState::new(
1593 self.frames.len(),
1594 FrameMode::MapValue {
1595 index: key_frame_index,
1596 },
1597 FrameFlags::ALLOCATED,
1598 ),
1599 };
1600
1601 trace!(
1602 "[{}] Pushing value of type {} for map {} with key type {}",
1603 self.frames.len(),
1604 value_shape.green(),
1605 map_shape.blue(),
1606 key_frame.shape.yellow(),
1607 );
1608
1609 self.frames.push(value_frame);
1610 Ok(self)
1611 }
1612
1613 pub fn pop(mut self) -> Result<Self, ReflectError> {
1615 let Some(frame) = self.pop_inner() else {
1616 return Err(ReflectError::InvariantViolation {
1617 invariant: "No frame to pop — it was time to call build()",
1618 });
1619 };
1620 self.track(frame);
1621 Ok(self)
1622 }
1623
1624 fn pop_inner(&mut self) -> Option<Frame> {
1625 let mut frame = self.frames.pop()?;
1626 #[cfg(feature = "log")]
1627 let frame_shape = frame.shape;
1628
1629 let init = frame.is_fully_initialized();
1630 trace!(
1631 "[{}] {} popped, {} initialized",
1632 self.frames.len(),
1633 frame_shape.blue(),
1634 if init {
1635 "✅ fully".style(owo_colors::Style::new().green())
1636 } else {
1637 "🚧 partially".style(owo_colors::Style::new().red())
1638 }
1639 );
1640 if init {
1641 if let Some(parent) = self.frames.last_mut() {
1642 if let Some(index) = frame.field_index_in_parent {
1643 parent.istate.fields.set(index);
1644 }
1645 }
1646 }
1647
1648 match frame.istate.mode {
1650 FrameMode::ListElement => {
1652 if frame.is_fully_initialized() {
1653 #[cfg(feature = "log")]
1656 let frame_len = self.frames.len();
1657
1658 let parent_frame = self.frames.last_mut().unwrap();
1660 let parent_shape = parent_frame.shape;
1661
1662 match parent_shape.def {
1664 Def::List(_) => {
1665 if let Def::List(list_def) = parent_shape.def {
1667 let list_vtable = list_def.vtable;
1668 trace!(
1669 "[{}] Pushing element to list {}",
1670 frame_len,
1671 parent_shape.blue()
1672 );
1673 unsafe {
1674 (list_vtable.push)(
1676 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1677 PtrMut::new(frame.data.as_mut_byte_ptr()),
1678 );
1679 self.mark_moved_out_of(&mut frame);
1680 }
1681 } else {
1682 panic!("parent frame is not a list type");
1683 }
1684 }
1685 _ => {
1686 panic!("Expected list or array, got {}", frame.shape);
1687 }
1688 }
1689 }
1690 }
1691
1692 FrameMode::MapValue {
1694 index: key_frame_index,
1695 } if frame.is_fully_initialized() => {
1696 let mut key_frame = self.frames.remove(key_frame_index);
1700
1701 if !key_frame.istate.fields.is_any_set() {
1703 panic!("key is not initialized when popping value frame");
1704 }
1705
1706 #[cfg(feature = "log")]
1708 let frame_len = self.frames.len();
1709 let parent_frame = self.frames.last_mut().unwrap();
1710 let parent_shape = parent_frame.shape;
1711
1712 match parent_shape.def {
1714 Def::Map(_) => {
1715 if let Def::Map(map_def) = parent_shape.def {
1717 trace!(
1718 "[{}] Inserting key-value pair into map {}",
1719 frame_len,
1720 parent_shape.blue()
1721 );
1722 unsafe {
1723 (map_def.vtable.insert_fn)(
1725 parent_frame.data.assume_init(),
1726 key_frame.data.assume_init(),
1727 PtrMut::new(frame.data.as_mut_byte_ptr()),
1728 );
1729 self.mark_moved_out_of(&mut key_frame);
1730 self.mark_moved_out_of(&mut frame);
1731 }
1732 } else {
1733 panic!("parent frame is not a map type");
1734 }
1735 }
1736 _ => {
1737 panic!("Expected map or hash map, got {}", frame.shape);
1738 }
1739 }
1740 }
1741
1742 FrameMode::OptionSome => {
1744 if frame.is_fully_initialized() {
1745 trace!("Popping OptionSome (fully init'd)");
1746
1747 #[cfg(feature = "log")]
1749 let frames_len = self.frames.len();
1750 let parent_frame = self.frames.last_mut().unwrap();
1751 let parent_shape = parent_frame.shape;
1752
1753 match parent_shape.def {
1755 Def::Option(option_def) => {
1756 trace!(
1757 "[{}] Setting Some value in option {}",
1758 frames_len,
1759 parent_shape.blue()
1760 );
1761 unsafe {
1762 (option_def.vtable.init_some_fn)(
1764 parent_frame.data,
1765 PtrConst::new(frame.data.as_byte_ptr()),
1766 );
1767 trace!("Marking parent frame as fully initialized");
1768 parent_frame.mark_fully_initialized();
1769
1770 self.mark_moved_out_of(&mut frame);
1771 }
1772 }
1773 _ => {
1774 panic!(
1775 "Expected parent frame to be an option type, got {}",
1776 frame.shape
1777 );
1778 }
1779 }
1780 } else {
1781 trace!("Popping OptionSome (not fully init'd)");
1782 }
1783 }
1784
1785 FrameMode::MapKey => {}
1788
1789 FrameMode::Field => {}
1791
1792 _ => {}
1794 }
1795
1796 Some(frame)
1797 }
1798
1799 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
1803 match frame.shape.def {
1804 Def::Struct(sd) => {
1805 for f in sd.fields {
1806 let id = ValueId {
1807 shape: f.shape(),
1808 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1809 };
1810 if let Some(istate) = self.istates.remove(&id) {
1811 let frame = Frame::recompose(id, istate);
1812 self.evict_tree(frame);
1813 } else {
1814 trace!("No istate found for field {}", f.name);
1815 }
1816 }
1817 }
1818 Def::Enum(_ed) => {
1819 if let Some(variant) = &frame.istate.variant {
1821 trace!(
1822 "Evicting enum {} variant '{}' fields",
1823 frame.shape.blue(),
1824 variant.name.yellow()
1825 );
1826 for field in variant.data.fields {
1828 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1830 let field_shape = field.shape();
1831 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1832
1833 if let Some(field_istate) = self.istates.remove(&field_id) {
1835 trace!(
1836 "Evicting field '{}' (shape {}) of enum variant '{}'",
1837 field.name.bright_blue(),
1838 field_shape.green(),
1839 variant.name.yellow()
1840 );
1841 let field_frame = Frame::recompose(field_id, field_istate);
1843 self.evict_tree(field_frame);
1845 } else {
1846 trace!(
1847 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1848 field.name.red(),
1849 field_shape.red(),
1850 variant.name.yellow()
1851 );
1852 }
1853 }
1854 } else {
1855 trace!(
1857 "Enum {} has no variant selected, no fields to evict.",
1858 frame.shape.blue()
1859 );
1860 }
1861 }
1862 _ => {}
1863 }
1864 frame
1865 }
1866
1867 #[allow(rustdoc::broken_intra_doc_links)]
1868 pub fn path(&self) -> String {
1871 let mut path = String::from("$");
1872
1873 for (i, frame) in self.frames.iter().enumerate() {
1874 if i == 0 {
1876 continue;
1877 }
1878
1879 match frame.istate.mode {
1880 FrameMode::ListElement => {
1881 if let Some(index) = frame.istate.list_index {
1883 path.push_str(&format!("[{}]", index));
1884 } else {
1885 path.push_str("[?]");
1886 }
1887 }
1888 FrameMode::MapKey => {
1889 path.push_str(".key");
1890 }
1891 FrameMode::MapValue { index: _ } => {
1892 path.push_str(".value");
1893 }
1894 FrameMode::OptionSome => {
1895 path.push_str(".some");
1896 }
1897 FrameMode::OptionNone => {
1898 path.push_str(".none");
1899 }
1900 FrameMode::Root => {
1901 }
1903 FrameMode::Field => {
1904 if let Some(index) = frame.field_index_in_parent {
1906 if let Some(parent) = self.frames.get(i - 1) {
1908 if let Def::Struct(sd) = parent.shape.def {
1909 if index < sd.fields.len() {
1910 let field_name = sd.fields[index].name;
1911 path.push('.');
1912 path.push_str(field_name);
1913 }
1914 } else if let Def::Enum(_) = parent.shape.def {
1915 if let Some(variant) = &parent.istate.variant {
1916 if index < variant.data.fields.len() {
1917 let field_name = variant.data.fields[index].name;
1918 path.push('.');
1919 path.push_str(field_name);
1920 }
1921 }
1922 }
1923 }
1924 }
1925 }
1926 }
1927 }
1928
1929 path
1930 }
1931
1932 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
1934 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
1935 shape: <()>::SHAPE,
1936 operation: "tried to check if field is set, but there was no frame",
1937 })?;
1938
1939 match frame.shape.def {
1940 Def::Struct(ref sd) => {
1941 if index >= sd.fields.len() {
1942 return Err(ReflectError::FieldError {
1943 shape: frame.shape,
1944 field_error: FieldError::NoSuchField,
1945 });
1946 }
1947 Ok(frame.istate.fields.has(index))
1948 }
1949 Def::Enum(_) => {
1950 let variant = frame.istate.variant.as_ref().ok_or(
1951 ReflectError::OperationFailed {
1952 shape: frame.shape,
1953 operation: "tried to check if field is set, but no variant was selected",
1954 },
1955 )?;
1956 if index >= variant.data.fields.len() {
1957 return Err(ReflectError::FieldError {
1958 shape: frame.shape,
1959 field_error: FieldError::NoSuchField,
1960 });
1961 }
1962 Ok(frame.istate.fields.has(index))
1963 }
1964 _ => Err(ReflectError::WasNotA {
1965 expected: "struct or enum",
1966 actual: frame.shape,
1967 }),
1968 }
1969 }
1970}
1971
1972impl Drop for Wip<'_> {
1973 fn drop(&mut self) {
1974 trace!("🧹🧹🧹 WIP is dropping");
1975
1976 while let Some(frame) = self.frames.pop() {
1977 self.track(frame);
1978 }
1979
1980 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
1981 trace!("No root found, we probably built already");
1982 return;
1983 };
1984
1985 let root_id = *root_id;
1986 let root_istate = self.istates.remove(&root_id).unwrap();
1987 let root = Frame::recompose(root_id, root_istate);
1988 let mut to_clean = vec![root];
1989
1990 let mut _root_guard: Option<Guard> = None;
1991
1992 while let Some(mut frame) = to_clean.pop() {
1993 trace!(
1994 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
1995 frame.shape.blue(),
1996 frame.data.as_byte_ptr(),
1997 frame.istate.flags.bright_magenta(),
1998 frame.istate.mode.yellow(),
1999 if frame.is_fully_initialized() {
2000 "✅"
2001 } else {
2002 "❌"
2003 }
2004 );
2005
2006 if frame.istate.flags.contains(FrameFlags::MOVED) {
2007 trace!(
2008 "{}",
2009 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
2010 );
2011 continue;
2012 }
2013
2014 match frame.shape.def {
2015 Def::Struct(sd) => {
2016 if frame.is_fully_initialized() {
2017 trace!(
2018 "Dropping fully initialized struct: {} at {:p}",
2019 frame.shape.green(),
2020 frame.data.as_byte_ptr()
2021 );
2022 let frame = self.evict_tree(frame);
2023 unsafe { frame.drop_and_dealloc_if_needed() };
2024 } else {
2025 let num_fields = sd.fields.len();
2026 trace!(
2027 "De-initializing struct {} at {:p} field-by-field ({} fields)",
2028 frame.shape.yellow(),
2029 frame.data.as_byte_ptr(),
2030 num_fields.to_string().bright_cyan()
2031 );
2032 for i in 0..num_fields {
2033 if frame.istate.fields.has(i) {
2034 let field = sd.fields[i];
2035 let field_shape = field.shape();
2036 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
2037 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2038 trace!(
2039 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
2040 i.to_string().bright_cyan(),
2041 field.name.bright_blue(),
2042 frame.shape.blue(),
2043 field_shape.green(),
2044 field_ptr.as_byte_ptr()
2045 );
2046 let istate = self.istates.remove(&field_id).unwrap();
2047 let field_frame = Frame::recompose(field_id, istate);
2048 to_clean.push(field_frame);
2049 } else {
2050 trace!(
2051 "Field #{} '{}' of {} was NOT initialized, skipping",
2052 i.to_string().bright_cyan(),
2053 sd.fields[i].name.bright_red(),
2054 frame.shape.red()
2055 );
2056 }
2057 }
2058
2059 if frame.istate.mode == FrameMode::Root {
2061 _root_guard = Some(Guard {
2062 ptr: frame.data.as_mut_byte_ptr(),
2063 layout: frame.shape.layout,
2064 });
2065 }
2066 }
2067 }
2068 Def::Enum(_ed) => {
2069 trace!(
2070 "{}",
2071 format_args!(
2072 "TODO: handle enum deallocation for {} at {:p}",
2073 frame.shape.yellow(),
2074 frame.data.as_byte_ptr()
2075 )
2076 .magenta()
2077 );
2078
2079 if frame.istate.mode == FrameMode::Root {
2081 _root_guard = Some(Guard {
2082 ptr: frame.data.as_mut_byte_ptr(),
2083 layout: frame.shape.layout,
2084 });
2085 }
2086 }
2087 Def::Array(_)
2088 | Def::Slice(_)
2089 | Def::List(_)
2090 | Def::Map(_)
2091 | Def::SmartPointer(_)
2092 | Def::Scalar(_)
2093 | Def::FunctionPointer(_)
2094 | Def::Option(_) => {
2095 trace!(
2096 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
2097 frame.shape.cyan(),
2098 frame.shape.def,
2099 frame.istate.mode.yellow(),
2100 frame.data.as_byte_ptr(),
2101 );
2102
2103 if frame.is_fully_initialized() {
2104 unsafe { frame.drop_and_dealloc_if_needed() }
2105 } else {
2106 frame.dealloc_if_needed();
2107 }
2108 }
2109 _ => {}
2110 }
2111 }
2112
2113 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
2115 for frame_id in all_ids.drain(..) {
2116 let frame_istate = self.istates.remove(&frame_id).unwrap();
2117
2118 trace!(
2119 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
2120 frame_id.shape.cyan(),
2121 frame_id.ptr,
2122 frame_istate.mode.yellow()
2123 );
2124 let mut frame = Frame::recompose(frame_id, frame_istate);
2125
2126 if frame.is_fully_initialized() {
2127 trace!("It's fully initialized, we can drop it");
2128 unsafe { frame.drop_and_dealloc_if_needed() };
2129 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
2130 trace!("Not initialized but allocated, let's free it");
2131 frame.dealloc_if_needed();
2132 }
2133 }
2134 }
2135}