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