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 match self.shape.layout {
82 facet_core::ShapeLayout::Sized(layout) => {
83 if layout.size() != 0 {
84 unsafe {
85 alloc::alloc::dealloc(self.data.as_mut_byte_ptr(), layout);
86 }
87 }
88 }
89 facet_core::ShapeLayout::Unsized => unimplemented!(),
90 }
91 self.istate.flags.remove(FrameFlags::ALLOCATED);
92 } else {
93 trace!(
94 "[{}] {:p} => NOT deallocating {} (not ALLOCATED)",
95 self.istate.depth,
96 self.data.as_mut_byte_ptr().magenta(),
97 self.shape.green(),
98 );
99 }
100 }
101}
102
103struct DebugToDisplay<T>(T);
104
105impl<T> fmt::Debug for DebugToDisplay<T>
106where
107 T: fmt::Display,
108{
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 fmt::Display::fmt(&self.0, f)
111 }
112}
113
114impl fmt::Debug for Frame {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 f.debug_struct("Frame")
117 .field("shape", &DebugToDisplay(&self.shape))
118 .field("kind", &def_kind(&self.shape.def))
119 .field("index", &self.field_index_in_parent)
120 .field("mode", &self.istate.mode)
121 .finish()
122 }
123}
124
125impl Frame {
126 fn id(&self) -> ValueId {
128 ValueId::new(self.shape, self.data.as_byte_ptr())
129 }
130
131 fn is_fully_initialized(&self) -> bool {
133 match self.shape.def {
134 Def::Struct(sd) => self.istate.fields.are_all_set(sd.fields.len()),
135 Def::Enum(_) => match self.istate.variant.as_ref() {
136 None => false,
137 Some(v) => self.istate.fields.are_all_set(v.data.fields.len()),
138 },
139 _ => self.istate.fields.are_all_set(1),
140 }
141 }
142
143 unsafe fn drop_and_dealloc_if_needed(mut self) {
145 trace!(
146 "[Frame::drop] Dropping frame for shape {} at {:p}",
147 self.shape.blue(),
148 self.data.as_byte_ptr()
149 );
150 if let Some(drop_in_place) = self.shape.vtable.drop_in_place {
151 unsafe {
152 trace!(
153 "[Frame::drop] Invoking drop_in_place for shape {} at {:p}",
154 self.shape.green(),
155 self.data.as_byte_ptr()
156 );
157 drop_in_place(self.data.assume_init());
158 }
159 } else {
160 trace!(
161 "[Frame::drop] No drop_in_place function for shape {}",
162 self.shape.blue(),
163 );
164 }
165 self.dealloc_if_needed();
166 }
167
168 unsafe fn mark_fully_initialized(&mut self) {
170 match self.shape.def {
171 Def::Struct(sd) => {
172 self.istate.fields = ISet::all(sd.fields);
173 }
174 Def::Enum(_) => {
175 if let Some(variant) = &self.istate.variant {
176 self.istate.fields = ISet::all(variant.data.fields);
177 }
178 }
179 _ => {
180 self.istate.fields.set(0);
181 }
182 }
183 }
184}
185
186struct IState {
188 variant: Option<Variant>,
190
191 fields: ISet,
193
194 depth: usize,
196
197 mode: FrameMode,
199
200 flags: FrameFlags,
202
203 list_index: Option<usize>,
205
206 #[allow(dead_code)]
208 map_key: Option<String>,
209}
210
211bitflags! {
212 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
214 pub struct FrameFlags: u64 {
215 const EMPTY = 0;
217
218 const ALLOCATED = 1 << 0;
220
221 const MOVED = 1 << 1;
225 }
226
227 }
229
230impl IState {
231 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
233 Self {
234 variant: None,
235 fields: Default::default(),
236 depth,
237 mode,
238 flags,
239 list_index: None,
240 map_key: None,
241 }
242 }
243
244 #[allow(dead_code)]
246 pub fn with_list_index(mut self, index: usize) -> Self {
247 self.list_index = Some(index);
248 self
249 }
250
251 #[allow(dead_code)]
253 pub fn with_map_key(mut self, key: String) -> Self {
254 self.map_key = Some(key);
255 self
256 }
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq)]
261pub enum FrameMode {
262 Root,
264 Field,
266 ListElement,
268 MapKey,
270 MapValue {
272 index: usize,
274 },
275 OptionSome,
277 OptionNone,
280}
281
282pub struct Wip<'facet_lifetime> {
284 frames: alloc::vec::Vec<Frame>,
286
287 istates: FlatMap<ValueId, IState>,
289
290 invariant: PhantomData<fn(&'facet_lifetime ()) -> &'facet_lifetime ()>,
291}
292
293impl<'facet_lifetime> Wip<'facet_lifetime> {
294 pub fn put_peek(
296 self,
297 peek: crate::Peek<'_, 'facet_lifetime>,
298 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
299 self.put_shape(peek.data, peek.shape)
300 }
301
302 pub fn frames_count(&self) -> usize {
304 self.frames.len()
305 }
306
307 pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
309 let data = shape
310 .allocate()
311 .map_err(|_| ReflectError::Unsized { shape })?;
312 Ok(Self {
313 frames: alloc::vec![Frame {
314 data,
315 shape,
316 field_index_in_parent: None,
317 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
318 }],
319 istates: Default::default(),
320 invariant: PhantomData,
321 })
322 }
323
324 pub fn alloc<S: Facet<'facet_lifetime>>() -> Result<Self, ReflectError> {
326 Self::alloc_shape(S::SHAPE)
327 }
328
329 fn track(&mut self, frame: Frame) {
330 if !frame.istate.flags.contains(FrameFlags::MOVED) {
336 self.istates.insert(frame.id(), frame.istate);
337 }
338 }
339
340 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame) {
341 frame.dealloc_if_needed();
342 ISet::clear(&mut frame.istate.fields);
343 frame.istate.variant = None;
344 frame.istate.flags.insert(FrameFlags::MOVED);
345 self.istates.remove(&frame.id());
348 }
349
350 pub fn shape(&self) -> &'static Shape {
352 self.frames.last().expect("must have frames left").shape
353 }
354
355 pub fn innermost_shape(&self) -> &'static Shape {
359 let mut current_shape = self.shape();
360
361 while let Some(inner_fn) = current_shape.inner {
363 current_shape = inner_fn();
364 }
365
366 current_shape
367 }
368
369 pub fn in_option(&self) -> bool {
371 let Some(frame) = self.frames.last() else {
372 return false;
373 };
374 matches!(frame.istate.mode, FrameMode::OptionSome)
375 }
376
377 pub fn mode(&self) -> FrameMode {
379 self.frames.last().unwrap().istate.mode
380 }
381
382 pub fn build(mut self) -> Result<HeapValue<'facet_lifetime>, ReflectError> {
384 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
385
386 while let Some(frame) = self.pop_inner() {
388 self.track(frame);
389 }
390
391 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
393 debug!("No root found, possibly already built or empty WIP");
394 return Err(ReflectError::OperationFailed {
395 shape: <()>::SHAPE,
396 operation: "tried to build a value but there was no root frame tracked",
397 });
398 };
399
400 let root_id = *root_id;
401 let root_istate = self
404 .istates
405 .remove(&root_id)
406 .expect("Root ID found but not present in istates, this is a bug"); let root_frame = Frame::recompose(root_id, root_istate);
409 let root_shape = root_frame.shape;
410 let root_data_ptr = root_frame.data; let root_layout = root_shape
412 .layout
413 .sized_layout()
414 .map_err(|_| ReflectError::Unsized { shape: root_shape })?;
415
416 let guard = Guard {
421 ptr: root_data_ptr.as_mut_byte_ptr(),
422 layout: root_layout,
423 };
424
425 let mut to_check = alloc::vec![root_frame];
427
428 while let Some(frame) = to_check.pop() {
430 trace!(
431 "Checking frame: shape={} at {:p}, flags={:?}, mode={:?}",
432 frame.shape.blue(),
433 frame.data.as_byte_ptr(),
434 frame.istate.flags.bright_magenta(),
435 frame.istate.mode,
436 );
437
438 if frame.istate.flags.contains(FrameFlags::MOVED) {
440 trace!(
441 "{}",
442 "Frame was moved out of, skipping initialization check".yellow()
443 );
444 continue;
445 }
446
447 match frame.shape.def {
449 Def::Struct(sd) => {
450 if !frame.is_fully_initialized() {
451 for i in 0..sd.fields.len() {
453 if !frame.istate.fields.has(i) {
454 let field = &sd.fields[i];
455 return Err(ReflectError::UninitializedField {
456 shape: frame.shape,
457 field_name: field.name,
458 });
459 }
460 }
461 unreachable!(
463 "Enum variant not fully initialized but couldn't find which field"
464 );
465 }
466
467 #[allow(clippy::unused_enumerate_index)]
469 for (_i, field) in sd.fields.iter().enumerate() {
470 let field_shape = field.shape();
471 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
472 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
473
474 if let Some(field_istate) = self.istates.remove(&field_id) {
475 debug!(
476 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
477 _i.to_string().bright_cyan(),
478 field.name.bright_blue(),
479 frame.shape.blue(),
480 field_shape.green(),
481 field_ptr.as_byte_ptr()
482 );
483 let field_frame = Frame::recompose(field_id, field_istate);
484 to_check.push(field_frame);
485 }
486 }
487 }
488 Def::Enum(_ed) => {
489 if let Some(variant) = &frame.istate.variant {
490 if !frame.istate.fields.are_all_set(variant.data.fields.len()) {
491 for (i, field) in variant.data.fields.iter().enumerate() {
493 if !frame.istate.fields.has(i) {
494 return Err(ReflectError::UninitializedEnumField {
495 shape: frame.shape,
496 variant_name: variant.name,
497 field_name: field.name,
498 });
499 }
500 }
501 unreachable!(
503 "Enum variant not fully initialized but couldn't find which field"
504 );
505 }
506
507 #[allow(clippy::unused_enumerate_index)]
509 for (_i, field) in variant.data.fields.iter().enumerate() {
510 let field_shape = field.shape();
511 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
515 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
516
517 if let Some(field_istate) = self.istates.remove(&field_id) {
518 debug!(
519 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
520 _i.to_string().bright_cyan(),
521 field.name.bright_blue(),
522 variant.name.yellow(),
523 frame.shape.blue(),
524 field_shape.green(),
525 field_ptr.as_byte_ptr()
526 );
527 let field_frame = Frame::recompose(field_id, field_istate);
528 to_check.push(field_frame);
529 }
530 }
531 } else {
532 return Err(ReflectError::NoVariantSelected { shape: frame.shape });
534 }
535 }
536 Def::List(_)
540 | Def::Map(_)
541 | Def::Option(_)
542 | Def::Scalar(_)
543 | Def::FunctionPointer(_)
544 | Def::SmartPointer(_)
545 | Def::Array(_)
546 | Def::Slice(_) => {
547 if !frame.istate.fields.are_all_set(1) {
548 match frame.istate.mode {
550 FrameMode::OptionNone => {
551 return Err(ReflectError::UninitializedValue {
553 shape: frame.shape,
554 });
555 }
556 _ => {
558 return Err(ReflectError::UninitializedValue {
559 shape: frame.shape,
560 });
561 }
562 }
563 }
564 }
572 _ => {
574 if !frame.istate.fields.are_all_set(1) {
576 return Err(ReflectError::UninitializedValue { shape: frame.shape });
577 }
578 }
579 }
580 }
581
582 debug!("All reachable frames checked and initialized.");
584
585 let data = unsafe { root_data_ptr.assume_init() };
587 if let Some(invariant_fn) = root_shape.vtable.invariants {
588 debug!(
589 "Checking invariants for root shape {} at {:p}",
590 root_shape.green(),
591 data.as_byte_ptr()
592 );
593 if !unsafe { invariant_fn(PtrConst::new(data.as_byte_ptr())) } {
594 return Err(ReflectError::InvariantViolation {
595 invariant: "Custom validation function returned false",
596 });
597 }
598 } else {
599 debug!(
600 "No invariants to check for root shape {}",
601 root_shape.blue()
602 );
603 }
604
605 FlatMap::clear(&mut self.istates); Ok(HeapValue {
608 guard: Some(guard),
609 shape: root_shape,
610 phantom: PhantomData,
611 })
612 }
613
614 pub fn field(mut self, index: usize) -> Result<Self, ReflectError> {
626 let frame = self.frames.last_mut().unwrap();
627 let shape = frame.shape;
628
629 let (field, field_offset) = match shape.def {
630 Def::Struct(def) => {
631 if index >= def.fields.len() {
632 return Err(ReflectError::FieldError {
633 shape,
634 field_error: FieldError::NoSuchField,
635 });
636 }
637 let field = &def.fields[index];
638 (field, field.offset)
639 }
640 Def::Enum(_) => {
641 let Some(variant) = frame.istate.variant.as_ref() else {
642 return Err(ReflectError::OperationFailed {
643 shape,
644 operation: "tried to access a field but no variant was selected",
645 });
646 };
647
648 if index >= variant.data.fields.len() {
649 return Err(ReflectError::FieldError {
650 shape,
651 field_error: FieldError::NoSuchField,
652 });
653 }
654
655 let field = &variant.data.fields[index];
656 (field, field.offset)
657 }
658 _ => {
659 return Err(ReflectError::WasNotA {
660 expected: "struct or enum",
661 actual: shape,
662 });
663 }
664 };
665
666 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
667
668 let mut frame = Frame {
669 data: field_data,
670 shape: field.shape(),
671 field_index_in_parent: Some(index),
672 istate: IState::new(self.frames.len(), FrameMode::Field, FrameFlags::EMPTY),
674 };
675 debug!(
676 "[{}] Selecting field {} ({}#{}) of {}",
677 self.frames.len(),
678 field.name.blue(),
679 field.shape().green(),
680 index.yellow(),
681 shape.blue(),
682 );
683 if let Some(iset) = self.istates.remove(&frame.id()) {
684 trace!(
685 "[{}] Restoring saved state for {} (istate.mode = {:?}, istate.fields = {:?}, istate.flags = {:?}, istate.depth = {:?})",
686 self.frames.len(),
687 frame.id().shape.blue(),
688 iset.mode,
689 iset.fields,
690 iset.flags,
691 iset.depth
692 );
693 frame.istate = iset;
694 } else {
695 trace!(
696 "[{}] no saved state for field {} ({}#{}) of {}",
697 self.frames.len(),
698 field.name.blue(),
699 field.shape().green(),
700 index.yellow(),
701 shape.blue(),
702 );
703 }
704 self.frames.push(frame);
705 Ok(self)
706 }
707
708 pub fn field_index(&self, name: &str) -> Option<usize> {
720 fn find_field_index(fields: &'static [facet_core::Field], name: &str) -> Option<usize> {
721 fields.iter().position(|f| f.name == name).or_else(|| {
722 fields
723 .iter()
724 .position(|f| f.get_rename_attr().is_some_and(|f_name| f_name == name))
725 })
726 }
727
728 let frame = self.frames.last()?;
729 match frame.shape.def {
730 Def::Struct(def) => find_field_index(def.fields, name),
731 Def::Enum(_) => {
732 let variant = frame.istate.variant.as_ref()?;
733 find_field_index(variant.data.fields, name)
734 }
735 _ => None,
736 }
737 }
738
739 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
751 let frame = self.frames.last().unwrap();
752 let shape = frame.shape;
753
754 if let Def::Enum(_) = shape.def {
756 if frame.istate.variant.is_none() {
757 return Err(ReflectError::OperationFailed {
758 shape,
759 operation: "tried to access a field by name but no variant was selected",
760 });
761 }
762 }
763
764 let index = self.field_index(name).ok_or(ReflectError::FieldError {
765 shape,
766 field_error: FieldError::NoSuchField,
767 })?;
768
769 self.field(index)
770 }
771
772 pub fn put<T: Facet<'facet_lifetime>>(
783 self,
784 t: T,
785 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
786 let shape = T::SHAPE;
787 let ptr_const = PtrConst::new(&t as *const T as *const u8);
788 let res = self.put_shape(ptr_const, shape);
789 core::mem::forget(t); res
791 }
792
793 pub fn try_put<T: Facet<'facet_lifetime>>(
804 self,
805 t: T,
806 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
807 let shape = T::SHAPE;
808 let ptr_const = PtrConst::new(&t as *const T as *const u8);
809 let res = self.put_shape(ptr_const, shape);
810 core::mem::forget(t); res
812 }
813
814 pub fn put_shape(
816 mut self,
817 src: PtrConst<'_>,
818 src_shape: &'static Shape,
819 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
820 let Some(frame) = self.frames.last_mut() else {
821 return Err(ReflectError::OperationFailed {
822 shape: src_shape,
823 operation: "tried to put a value but there was no frame to put into",
824 });
825 };
826
827 if frame.shape != src_shape {
829 trace!(
830 "Trying to put a {} into a {}",
831 src_shape.yellow(),
832 frame.shape.magenta()
833 );
834
835 if let Some(inner_fn) = frame.shape.inner {
837 let inner_shape = inner_fn();
839
840 if src_shape == inner_shape {
842 if let Some(try_from_inner_fn) = frame.shape.vtable.try_from_inner {
844 match unsafe { (try_from_inner_fn)(src, src_shape, frame.data) } {
845 Ok(_) => {
846 unsafe {
847 frame.mark_fully_initialized();
848 }
849
850 let shape = frame.shape;
851 let index = frame.field_index_in_parent;
852
853 self.mark_field_as_initialized(shape, index)?;
855
856 debug!(
857 "[{}] Just put a {} value into transparent type {}",
858 self.frames.len(),
859 src_shape.green(),
860 shape.blue()
861 );
862
863 return Ok(self);
864 }
865 Err(e) => {
866 return Err(ReflectError::TryFromInnerError {
867 inner: e,
868 src_shape,
869 dst_shape: frame.shape,
870 });
871 }
872 }
873 } else {
874 debug!(
876 "No try_from_inner function for transparent type, falling back to TryFrom"
877 );
878 }
879 }
880 }
881
882 if let Some(try_from) = frame.shape.vtable.try_from {
884 match unsafe { try_from(src, src_shape, frame.data) } {
885 Ok(_) => {
886 unsafe {
887 frame.mark_fully_initialized();
888 }
889
890 let shape = frame.shape;
891 let index = frame.field_index_in_parent;
892
893 self.mark_field_as_initialized(shape, index)?;
895
896 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
897
898 return Ok(self);
899 }
900 Err(e) => {
901 return Err(ReflectError::TryFromError {
902 inner: e,
903 src_shape,
904 dst_shape: frame.shape,
905 });
906 }
907 }
908 }
909
910 if let Def::Option(od) = frame.shape.def {
913 if od.t() == src_shape {
915 debug!("Putting into an Option<T>!");
916 if frame.istate.fields.is_any_set() {
917 let data = unsafe { frame.data.assume_init() };
918 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
919 } else {
920 let data = frame.data;
921 unsafe { (od.vtable.init_some_fn)(data, src) };
922 }
923 unsafe {
924 frame.mark_fully_initialized();
925 }
926
927 let shape = frame.shape;
928 let index = frame.field_index_in_parent;
929
930 self.mark_field_as_initialized(shape, index)?;
932
933 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
934
935 return Ok(self);
936 }
937 }
938
939 if let Def::Struct(sd) = frame.shape.def {
943 for (i, field) in sd.fields.iter().enumerate() {
945 if !frame.istate.fields.has(i) && field.shape() == src_shape {
946 debug!(
947 "Found uninitialized field {} with matching type {}",
948 i.to_string().blue(),
949 src_shape.green()
950 );
951
952 unsafe {
954 let field_data = frame.data.field_uninit_at(field.offset);
955 field_data.copy_from(src, field.shape()).map_err(|_| {
956 ReflectError::Unsized {
957 shape: field.shape(),
958 }
959 })?;
960 frame.istate.fields.set(i);
961 }
962
963 let shape = frame.shape;
964 let index = frame.field_index_in_parent;
965
966 if frame.is_fully_initialized() {
968 self.mark_field_as_initialized(shape, index)?;
969 }
970
971 debug!(
972 "[{}] Put a {} value into field {} of {}",
973 self.frames.len(),
974 src_shape.green(),
975 i.to_string().blue(),
976 shape.green()
977 );
978
979 return Ok(self);
980 }
981 }
982 }
983
984 if let Def::Enum(_) = frame.shape.def {
987 if let Some(variant) = &frame.istate.variant {
989 for (i, field) in variant.data.fields.iter().enumerate() {
991 if !frame.istate.fields.has(i) && field.shape() == src_shape {
992 debug!(
993 "Found uninitialized field {} in enum variant '{}' with matching type {}",
994 i.to_string().blue(),
995 variant.name.bright_yellow(),
996 src_shape.green()
997 );
998
999 unsafe {
1001 let field_data = frame.data.field_uninit_at(field.offset);
1002 field_data.copy_from(src, field.shape()).map_err(|_| {
1003 ReflectError::Unsized {
1004 shape: field.shape(),
1005 }
1006 })?;
1007 frame.istate.fields.set(i);
1008 }
1009
1010 let shape = frame.shape;
1011 let index = frame.field_index_in_parent;
1012
1013 #[allow(unused)]
1014 let variant_name = variant.name;
1015
1016 if frame.is_fully_initialized() {
1018 self.mark_field_as_initialized(shape, index)?;
1019 }
1020
1021 debug!(
1022 "[{}] Put a {} value into field {} of variant '{}' in enum {}",
1023 self.frames.len(),
1024 src_shape.green(),
1025 i.to_string().blue(),
1026 variant_name.bright_yellow(),
1027 shape.green()
1028 );
1029
1030 return Ok(self);
1031 }
1032 }
1033 }
1034 }
1035
1036 return Err(ReflectError::WrongShape {
1037 expected: frame.shape,
1038 actual: src_shape,
1039 });
1040 }
1041
1042 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
1044 debug!(
1045 "De-initializing partially initialized fields for {}",
1046 frame.shape
1047 );
1048
1049 match frame.shape.def {
1050 Def::Struct(sd) => {
1051 for (i, field) in sd.fields.iter().enumerate() {
1052 if frame.istate.fields.has(i) {
1053 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1054 unsafe {
1055 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
1056 drop_fn(PtrMut::new(field_ptr));
1057 }
1058 }
1059 }
1060 }
1061 }
1062 Def::Enum(_) => {
1063 if let Some(variant) = &frame.istate.variant {
1064 for (i, field) in variant.data.fields.iter().enumerate() {
1065 if frame.istate.fields.has(i) {
1066 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1067 unsafe {
1068 let field_ptr =
1069 frame.data.as_mut_byte_ptr().add(field.offset);
1070 drop_fn(PtrMut::new(field_ptr));
1071 }
1072 }
1073 }
1074 }
1075 }
1076 }
1077 _ => {
1078 }
1080 }
1081
1082 frame.istate.variant = None;
1084 ISet::clear(&mut frame.istate.fields);
1085 }
1086
1087 unsafe {
1088 frame
1090 .data
1091 .copy_from(src, frame.shape)
1092 .map_err(|_| ReflectError::Unsized { shape: frame.shape })?;
1093 frame.mark_fully_initialized();
1094 }
1095
1096 let shape = frame.shape;
1097 let index = frame.field_index_in_parent;
1098
1099 self.mark_field_as_initialized(shape, index)?;
1101
1102 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1103
1104 Ok(self)
1105 }
1106
1107 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
1109 let Some(frame) = self.frames.last_mut() else {
1110 return Err(ReflectError::OperationFailed {
1111 shape: <()>::SHAPE,
1112 operation: "tried to parse value but there was no frame",
1113 });
1114 };
1115
1116 let shape = frame.shape;
1117 let index = frame.field_index_in_parent;
1118
1119 let Some(parse_fn) = frame.shape.vtable.parse else {
1120 return Err(ReflectError::OperationFailed {
1121 shape: frame.shape,
1122 operation: "type does not implement Parse",
1123 });
1124 };
1125 match unsafe { (parse_fn)(s, frame.data) } {
1126 Ok(_res) => {
1127 unsafe {
1128 frame.mark_fully_initialized();
1129 }
1130
1131 self.mark_field_as_initialized(shape, index)?;
1133
1134 Ok(self)
1135 }
1136 Err(_) => Err(ReflectError::OperationFailed {
1137 shape,
1138 operation: "parsing",
1139 }),
1140 }
1141 }
1142
1143 pub fn put_from_fn(mut self, default_in_place: DefaultInPlaceFn) -> Result<Self, ReflectError> {
1145 let Some(frame) = self.frames.last_mut() else {
1146 return Err(ReflectError::OperationFailed {
1147 shape: <()>::SHAPE,
1148 operation: "tried to put value from fn but there was no frame",
1149 });
1150 };
1151
1152 unsafe {
1153 default_in_place(frame.data);
1154 frame.mark_fully_initialized();
1155 }
1156
1157 let shape = frame.shape;
1158 let index = frame.field_index_in_parent;
1159
1160 self.mark_field_as_initialized(shape, index)?;
1162
1163 Ok(self)
1164 }
1165
1166 pub fn put_default(self) -> Result<Self, ReflectError> {
1168 let Some(frame) = self.frames.last() else {
1169 return Err(ReflectError::OperationFailed {
1170 shape: <()>::SHAPE,
1171 operation: "tried to put default value but there was no frame",
1172 });
1173 };
1174
1175 let vtable = frame.shape.vtable;
1176 let Some(default_in_place) = vtable.default_in_place else {
1177 return Err(ReflectError::OperationFailed {
1178 shape: frame.shape,
1179 operation: "type does not implement Default",
1180 });
1181 };
1182
1183 self.put_from_fn(default_in_place)
1184 }
1185
1186 fn mark_field_as_initialized(
1188 &mut self,
1189 shape: &'static Shape,
1190 index: Option<usize>,
1191 ) -> Result<(), ReflectError> {
1192 if let Some(index) = index {
1193 let parent_index = self.frames.len().saturating_sub(2);
1194 #[cfg(feature = "log")]
1195 let num_frames = self.frames.len();
1196 let Some(parent) = self.frames.get_mut(parent_index) else {
1197 return Err(ReflectError::OperationFailed {
1198 shape,
1199 operation: "was supposed to mark a field as initialized, but there was no parent frame",
1200 });
1201 };
1202 #[cfg(feature = "log")]
1203 let parent_shape = parent.shape;
1204 trace!(
1205 "[{}] {}.{} initialized with {}",
1206 num_frames,
1207 parent_shape.blue(),
1208 index.yellow(),
1209 shape.green()
1210 );
1211
1212 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
1213 return Err(ReflectError::OperationFailed {
1214 shape,
1215 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
1216 });
1217 }
1218
1219 if parent.istate.fields.has(index) {
1220 return Err(ReflectError::OperationFailed {
1221 shape,
1222 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
1223 });
1224 }
1225
1226 parent.istate.fields.set(index);
1227 }
1228 Ok(())
1229 }
1230
1231 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
1233 let frame = self.frames.last().unwrap();
1234 let shape = frame.shape;
1235
1236 match shape.def {
1237 Def::List(list_def) => Ok(list_def.t()),
1238 _ => Err(ReflectError::WasNotA {
1239 expected: "list or array",
1240 actual: shape,
1241 }),
1242 }
1243 }
1244
1245 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
1247 let frame = self.frames.last().unwrap();
1248 let shape = frame.shape;
1249
1250 match shape.def {
1251 Def::Map(map_def) => Ok(map_def.k),
1252 _ => Err(ReflectError::WasNotA {
1253 expected: "map",
1254 actual: shape,
1255 }),
1256 }
1257 }
1258
1259 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
1261 let Some(frame) = self.frames.last_mut() else {
1262 return Err(ReflectError::OperationFailed {
1263 shape: <()>::SHAPE,
1264 operation: "tried to create empty list but there was no frame",
1265 });
1266 };
1267
1268 if !matches!(frame.shape.def, Def::List(_)) {
1269 return Err(ReflectError::WasNotA {
1270 expected: "list or array",
1271 actual: frame.shape,
1272 });
1273 }
1274
1275 let vtable = frame.shape.vtable;
1276
1277 let Some(default_in_place) = vtable.default_in_place else {
1279 return Err(ReflectError::OperationFailed {
1280 shape: frame.shape,
1281 operation: "list type does not implement Default",
1282 });
1283 };
1284
1285 unsafe {
1286 default_in_place(frame.data);
1287 frame.mark_fully_initialized();
1288 }
1289
1290 let shape = frame.shape;
1291 let index = frame.field_index_in_parent;
1292
1293 self.mark_field_as_initialized(shape, index)?;
1295
1296 Ok(self)
1297 }
1298
1299 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1301 let Some(frame) = self.frames.last_mut() else {
1302 return Err(ReflectError::OperationFailed {
1303 shape: <()>::SHAPE,
1304 operation: "tried to create empty map but there was no frame",
1305 });
1306 };
1307
1308 if !matches!(frame.shape.def, Def::Map(_)) {
1309 return Err(ReflectError::WasNotA {
1310 expected: "map or hash map",
1311 actual: frame.shape,
1312 });
1313 }
1314
1315 let vtable = frame.shape.vtable;
1316
1317 let Some(default_in_place) = vtable.default_in_place else {
1319 return Err(ReflectError::OperationFailed {
1320 shape: frame.shape,
1321 operation: "map type does not implement Default",
1322 });
1323 };
1324
1325 unsafe {
1326 default_in_place(frame.data);
1327 frame.mark_fully_initialized();
1328 }
1329
1330 let shape = frame.shape;
1331 let index = frame.field_index_in_parent;
1332
1333 self.mark_field_as_initialized(shape, index)?;
1335
1336 Ok(self)
1337 }
1338
1339 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1341 let Some(frame) = self.frames.last_mut() else {
1342 return Err(ReflectError::OperationFailed {
1343 shape: <()>::SHAPE,
1344 operation: "tried to begin pushback but there was no frame",
1345 });
1346 };
1347
1348 if !matches!(frame.shape.def, Def::List(_)) {
1349 return Err(ReflectError::WasNotA {
1350 expected: "list or array",
1351 actual: frame.shape,
1352 });
1353 }
1354
1355 let vtable = frame.shape.vtable;
1356
1357 if !frame.istate.fields.has(0) {
1359 let Some(default_in_place) = vtable.default_in_place else {
1360 return Err(ReflectError::OperationFailed {
1361 shape: frame.shape,
1362 operation: "list type does not implement Default",
1363 });
1364 };
1365
1366 unsafe {
1367 default_in_place(frame.data);
1368 frame.istate.fields.set(0);
1369 }
1370 }
1371
1372 Ok(self)
1373 }
1374
1375 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1377 let Some(frame) = self.frames.last_mut() else {
1378 return Err(ReflectError::OperationFailed {
1379 shape: <()>::SHAPE,
1380 operation: "tried to begin map insertion but there was no frame",
1381 });
1382 };
1383
1384 if !matches!(frame.shape.def, Def::Map(_)) {
1385 return Err(ReflectError::WasNotA {
1386 expected: "map or hash map",
1387 actual: frame.shape,
1388 });
1389 }
1390
1391 let vtable = frame.shape.vtable;
1392
1393 if !frame.istate.fields.has(0) {
1395 let Some(default_in_place) = vtable.default_in_place else {
1396 return Err(ReflectError::OperationFailed {
1397 shape: frame.shape,
1398 operation: "map type does not implement Default",
1399 });
1400 };
1401
1402 unsafe {
1403 default_in_place(frame.data);
1404 frame.istate.fields.set(0);
1405 }
1406 }
1407
1408 Ok(self)
1409 }
1410
1411 pub fn push(mut self) -> Result<Self, ReflectError> {
1416 let frame = self.frames.last().unwrap();
1418 let list_shape = frame.shape;
1419
1420 if !matches!(list_shape.def, Def::List(_)) {
1421 return Err(ReflectError::WasNotA {
1422 expected: "list or array",
1423 actual: list_shape,
1424 });
1425 }
1426
1427 if !frame.istate.fields.has(0) {
1429 self = self.begin_pushback()?;
1430 }
1431
1432 let element_shape = self.element_shape()?;
1434
1435 let element_data = element_shape
1437 .allocate()
1438 .map_err(|_| ReflectError::Unsized {
1439 shape: element_shape,
1440 })?;
1441
1442 let element_frame = Frame {
1444 data: element_data,
1445 shape: element_shape,
1446 field_index_in_parent: None, istate: IState::new(
1448 self.frames.len(),
1449 FrameMode::ListElement,
1450 FrameFlags::ALLOCATED,
1451 ),
1452 };
1453
1454 trace!(
1455 "[{}] Pushing element of type {} to list {}",
1456 self.frames.len(),
1457 element_shape.green(),
1458 list_shape.blue(),
1459 );
1460
1461 self.frames.push(element_frame);
1462 Ok(self)
1463 }
1464
1465 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1467 let frame = self.frames.last().unwrap();
1469 let option_shape = frame.shape;
1470
1471 let Def::Option(option_def) = option_shape.def else {
1473 return Err(ReflectError::WasNotA {
1474 expected: "option",
1475 actual: option_shape,
1476 });
1477 };
1478
1479 let inner_shape = option_def.t();
1481
1482 let inner_data = inner_shape
1484 .allocate()
1485 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1486
1487 let inner_frame = Frame {
1489 data: inner_data,
1490 shape: inner_shape,
1491 field_index_in_parent: None,
1493 istate: IState::new(
1494 self.frames.len(),
1495 FrameMode::OptionSome,
1496 FrameFlags::ALLOCATED,
1498 ),
1499 };
1500
1501 trace!(
1502 "[{}] Pushing option frame for {}",
1503 self.frames.len(),
1504 option_shape.blue(),
1505 );
1506
1507 self.frames.push(inner_frame);
1508 Ok(self)
1509 }
1510
1511 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1521 let Some(frame) = self.frames.last_mut() else {
1523 return Err(ReflectError::OperationFailed {
1524 shape: <()>::SHAPE,
1525 operation: "tried to pop_some_push_none but there was no frame",
1526 });
1527 };
1528
1529 if frame.istate.mode != FrameMode::OptionSome {
1531 return Err(ReflectError::OperationFailed {
1532 shape: frame.shape,
1533 operation: "pop_some_push_none called, but frame was not in Option mode",
1534 });
1535 }
1536
1537 if frame.is_fully_initialized() {
1539 return Err(ReflectError::OperationFailed {
1540 shape: frame.shape,
1541 operation: "option frame already initialized, cannot pop_some_push_none",
1542 });
1543 }
1544
1545 frame.dealloc_if_needed();
1546
1547 let _frame = self.frames.pop().expect("frame already checked");
1549
1550 let parent_frame = self
1552 .frames
1553 .last_mut()
1554 .ok_or(ReflectError::OperationFailed {
1555 shape: <()>::SHAPE,
1556 operation: "tried to pop_some_push_none but there was no parent frame",
1557 })?;
1558
1559 unsafe {
1561 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1562 default_fn(parent_frame.data);
1563 } else {
1564 return Err(ReflectError::OperationFailed {
1565 shape: parent_frame.shape,
1566 operation: "option type does not implement Default",
1567 });
1568 }
1569 parent_frame.mark_fully_initialized();
1570 }
1571
1572 let Def::Option(od) = parent_frame.shape.def else {
1573 return Err(ReflectError::OperationFailed {
1574 shape: parent_frame.shape,
1575 operation: "pop_some_push_none and the parent isn't of type Option???",
1576 });
1577 };
1578
1579 let data = parent_frame.data;
1581
1582 let mut frame = Frame {
1583 data,
1584 shape: od.t(),
1585 field_index_in_parent: Some(0),
1586 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1587 };
1588 unsafe {
1589 frame.mark_fully_initialized();
1590 }
1591
1592 self.frames.push(frame);
1593
1594 Ok(self)
1595 }
1596
1597 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1602 let frame = self.frames.last().unwrap();
1604 let map_shape = frame.shape;
1605
1606 if !matches!(map_shape.def, Def::Map(_)) {
1607 return Err(ReflectError::WasNotA {
1608 expected: "map or hash map",
1609 actual: map_shape,
1610 });
1611 }
1612
1613 if !frame.istate.fields.has(0) {
1615 self = self.begin_map_insert()?;
1616 }
1617
1618 let key_shape = self.key_shape()?;
1620
1621 let key_data = key_shape
1623 .allocate()
1624 .map_err(|_| ReflectError::Unsized { shape: key_shape })?;
1625
1626 let key_frame = Frame {
1628 data: key_data,
1629 shape: key_shape,
1630 field_index_in_parent: None,
1631 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1632 };
1633
1634 trace!(
1635 "[{}] Pushing key of type {} for map {}",
1636 self.frames.len(),
1637 key_shape.green(),
1638 map_shape.blue(),
1639 );
1640
1641 self.frames.push(key_frame);
1642 Ok(self)
1643 }
1644
1645 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1650 trace!("Wants to push map value. Frames = ");
1651 #[cfg(feature = "log")]
1652 for (i, f) in self.frames.iter().enumerate() {
1653 trace!("Frame {}: {:?}", i, f);
1654 }
1655
1656 if self.frames.len() < 2 {
1658 return Err(ReflectError::OperationFailed {
1659 shape: <()>::SHAPE,
1660 operation: "tried to push map value but there was no key frame",
1661 });
1662 }
1663
1664 let key_frame_index = self.frames.len() - 1;
1666 let key_frame = &self.frames[key_frame_index];
1667
1668 match key_frame.istate.mode {
1670 FrameMode::MapKey => {} _ => {
1672 return Err(ReflectError::OperationFailed {
1673 shape: key_frame.shape,
1674 operation: "current frame is not a map key",
1675 });
1676 }
1677 }
1678
1679 if !key_frame.is_fully_initialized() {
1681 return Err(ReflectError::OperationFailed {
1682 shape: key_frame.shape,
1683 operation: "map key is not fully initialized",
1684 });
1685 }
1686
1687 let map_frame_index = self.frames.len() - 2;
1689 let map_frame = &self.frames[map_frame_index];
1690 let map_shape = map_frame.shape;
1691
1692 let Def::Map(map_def) = map_shape.def else {
1693 return Err(ReflectError::WasNotA {
1694 expected: "map",
1695 actual: map_frame.shape,
1696 });
1697 };
1698
1699 let value_shape = map_def.v;
1700
1701 let value_data = value_shape
1703 .allocate()
1704 .map_err(|_| ReflectError::Unsized { shape: value_shape })?;
1705
1706 let value_frame = Frame {
1708 data: value_data,
1709 shape: value_shape,
1710 field_index_in_parent: None,
1711 istate: IState::new(
1712 self.frames.len(),
1713 FrameMode::MapValue {
1714 index: key_frame_index,
1715 },
1716 FrameFlags::ALLOCATED,
1717 ),
1718 };
1719
1720 trace!(
1721 "[{}] Pushing value of type {} for map {} with key type {}",
1722 self.frames.len(),
1723 value_shape.green(),
1724 map_shape.blue(),
1725 key_frame.shape.yellow(),
1726 );
1727
1728 self.frames.push(value_frame);
1729 Ok(self)
1730 }
1731
1732 pub fn pop(mut self) -> Result<Self, ReflectError> {
1734 let Some(frame) = self.pop_inner() else {
1735 return Err(ReflectError::InvariantViolation {
1736 invariant: "No frame to pop — it was time to call build()",
1737 });
1738 };
1739 self.track(frame);
1740 Ok(self)
1741 }
1742
1743 fn pop_inner(&mut self) -> Option<Frame> {
1744 let mut frame = self.frames.pop()?;
1745 #[cfg(feature = "log")]
1746 let frame_shape = frame.shape;
1747
1748 let init = frame.is_fully_initialized();
1749 trace!(
1750 "[{}] {} popped, {} initialized",
1751 self.frames.len(),
1752 frame_shape.blue(),
1753 if init {
1754 "✅ fully".style(owo_colors::Style::new().green())
1755 } else {
1756 "🚧 partially".style(owo_colors::Style::new().red())
1757 }
1758 );
1759 if init {
1760 if let Some(parent) = self.frames.last_mut() {
1761 if let Some(index) = frame.field_index_in_parent {
1762 parent.istate.fields.set(index);
1763 }
1764 }
1765 }
1766
1767 match frame.istate.mode {
1769 FrameMode::ListElement => {
1771 if frame.is_fully_initialized() {
1772 #[cfg(feature = "log")]
1775 let frame_len = self.frames.len();
1776
1777 let parent_frame = self.frames.last_mut().unwrap();
1779 let parent_shape = parent_frame.shape;
1780
1781 match parent_shape.def {
1783 Def::List(_) => {
1784 if let Def::List(list_def) = parent_shape.def {
1786 let list_vtable = list_def.vtable;
1787 trace!(
1788 "[{}] Pushing element to list {}",
1789 frame_len,
1790 parent_shape.blue()
1791 );
1792 unsafe {
1793 (list_vtable.push)(
1795 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1796 PtrMut::new(frame.data.as_mut_byte_ptr()),
1797 );
1798 self.mark_moved_out_of(&mut frame);
1799 }
1800 } else {
1801 panic!("parent frame is not a list type");
1802 }
1803 }
1804 _ => {
1805 panic!("Expected list or array, got {}", frame.shape);
1806 }
1807 }
1808 }
1809 }
1810
1811 FrameMode::MapValue {
1813 index: key_frame_index,
1814 } if frame.is_fully_initialized() => {
1815 let mut key_frame = self.frames.remove(key_frame_index);
1819
1820 if !key_frame.istate.fields.is_any_set() {
1822 panic!("key is not initialized when popping value frame");
1823 }
1824
1825 #[cfg(feature = "log")]
1827 let frame_len = self.frames.len();
1828 let parent_frame = self.frames.last_mut().unwrap();
1829 let parent_shape = parent_frame.shape;
1830
1831 match parent_shape.def {
1833 Def::Map(_) => {
1834 if let Def::Map(map_def) = parent_shape.def {
1836 trace!(
1837 "[{}] Inserting key-value pair into map {}",
1838 frame_len,
1839 parent_shape.blue()
1840 );
1841 unsafe {
1842 (map_def.vtable.insert_fn)(
1844 parent_frame.data.assume_init(),
1845 key_frame.data.assume_init(),
1846 PtrMut::new(frame.data.as_mut_byte_ptr()),
1847 );
1848 self.mark_moved_out_of(&mut key_frame);
1849 self.mark_moved_out_of(&mut frame);
1850 }
1851 } else {
1852 panic!("parent frame is not a map type");
1853 }
1854 }
1855 _ => {
1856 panic!("Expected map or hash map, got {}", frame.shape);
1857 }
1858 }
1859 }
1860
1861 FrameMode::OptionSome => {
1863 if frame.is_fully_initialized() {
1864 trace!("Popping OptionSome (fully init'd)");
1865
1866 #[cfg(feature = "log")]
1868 let frames_len = self.frames.len();
1869 let parent_frame = self.frames.last_mut().unwrap();
1870 let parent_shape = parent_frame.shape;
1871
1872 match parent_shape.def {
1874 Def::Option(option_def) => {
1875 trace!(
1876 "[{}] Setting Some value in option {}",
1877 frames_len,
1878 parent_shape.blue()
1879 );
1880 unsafe {
1881 (option_def.vtable.init_some_fn)(
1883 parent_frame.data,
1884 PtrConst::new(frame.data.as_byte_ptr()),
1885 );
1886 trace!("Marking parent frame as fully initialized");
1887 parent_frame.mark_fully_initialized();
1888
1889 self.mark_moved_out_of(&mut frame);
1890 }
1891 }
1892 _ => {
1893 panic!(
1894 "Expected parent frame to be an option type, got {}",
1895 frame.shape
1896 );
1897 }
1898 }
1899 } else {
1900 trace!("Popping OptionSome (not fully init'd)");
1901 }
1902 }
1903
1904 FrameMode::MapKey => {}
1907
1908 FrameMode::Field => {}
1910
1911 _ => {}
1913 }
1914
1915 Some(frame)
1916 }
1917
1918 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
1922 match frame.shape.def {
1923 Def::Struct(sd) => {
1924 for f in sd.fields {
1925 let id = ValueId {
1926 shape: f.shape(),
1927 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1928 };
1929 if let Some(istate) = self.istates.remove(&id) {
1930 let frame = Frame::recompose(id, istate);
1931 self.evict_tree(frame);
1932 } else {
1933 trace!("No istate found for field {}", f.name);
1934 }
1935 }
1936 }
1937 Def::Enum(_ed) => {
1938 if let Some(variant) = &frame.istate.variant {
1940 trace!(
1941 "Evicting enum {} variant '{}' fields",
1942 frame.shape.blue(),
1943 variant.name.yellow()
1944 );
1945 for field in variant.data.fields {
1947 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1949 let field_shape = field.shape();
1950 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1951
1952 if let Some(field_istate) = self.istates.remove(&field_id) {
1954 trace!(
1955 "Evicting field '{}' (shape {}) of enum variant '{}'",
1956 field.name.bright_blue(),
1957 field_shape.green(),
1958 variant.name.yellow()
1959 );
1960 let field_frame = Frame::recompose(field_id, field_istate);
1962 self.evict_tree(field_frame);
1964 } else {
1965 trace!(
1966 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1967 field.name.red(),
1968 field_shape.red(),
1969 variant.name.yellow()
1970 );
1971 }
1972 }
1973 } else {
1974 trace!(
1976 "Enum {} has no variant selected, no fields to evict.",
1977 frame.shape.blue()
1978 );
1979 }
1980 }
1981 _ => {}
1982 }
1983 frame
1984 }
1985
1986 #[allow(rustdoc::broken_intra_doc_links)]
1987 pub fn path(&self) -> String {
1990 let mut path = String::from("$");
1991
1992 for (i, frame) in self.frames.iter().enumerate() {
1993 if i == 0 {
1995 continue;
1996 }
1997
1998 match frame.istate.mode {
1999 FrameMode::ListElement => {
2000 if let Some(index) = frame.istate.list_index {
2002 path.push_str(&format!("[{}]", index));
2003 } else {
2004 path.push_str("[?]");
2005 }
2006 }
2007 FrameMode::MapKey => {
2008 path.push_str(".key");
2009 }
2010 FrameMode::MapValue { index: _ } => {
2011 path.push_str(".value");
2012 }
2013 FrameMode::OptionSome => {
2014 path.push_str(".some");
2015 }
2016 FrameMode::OptionNone => {
2017 path.push_str(".none");
2018 }
2019 FrameMode::Root => {
2020 }
2022 FrameMode::Field => {
2023 if let Some(index) = frame.field_index_in_parent {
2025 if let Some(parent) = self.frames.get(i - 1) {
2027 if let Def::Struct(sd) = parent.shape.def {
2028 if index < sd.fields.len() {
2029 let field_name = sd.fields[index].name;
2030 path.push('.');
2031 path.push_str(field_name);
2032 }
2033 } else if let Def::Enum(_) = parent.shape.def {
2034 if let Some(variant) = &parent.istate.variant {
2035 if index < variant.data.fields.len() {
2036 let field_name = variant.data.fields[index].name;
2037 path.push('.');
2038 path.push_str(field_name);
2039 }
2040 }
2041 }
2042 }
2043 }
2044 }
2045 }
2046 }
2047
2048 path
2049 }
2050
2051 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
2053 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
2054 shape: <()>::SHAPE,
2055 operation: "tried to check if field is set, but there was no frame",
2056 })?;
2057
2058 match frame.shape.def {
2059 Def::Struct(ref sd) => {
2060 if index >= sd.fields.len() {
2061 return Err(ReflectError::FieldError {
2062 shape: frame.shape,
2063 field_error: FieldError::NoSuchField,
2064 });
2065 }
2066 Ok(frame.istate.fields.has(index))
2067 }
2068 Def::Enum(_) => {
2069 let variant = frame.istate.variant.as_ref().ok_or(
2070 ReflectError::OperationFailed {
2071 shape: frame.shape,
2072 operation: "tried to check if field is set, but no variant was selected",
2073 },
2074 )?;
2075 if index >= variant.data.fields.len() {
2076 return Err(ReflectError::FieldError {
2077 shape: frame.shape,
2078 field_error: FieldError::NoSuchField,
2079 });
2080 }
2081 Ok(frame.istate.fields.has(index))
2082 }
2083 _ => Err(ReflectError::WasNotA {
2084 expected: "struct or enum",
2085 actual: frame.shape,
2086 }),
2087 }
2088 }
2089}
2090
2091impl Drop for Wip<'_> {
2092 fn drop(&mut self) {
2093 trace!("🧹🧹🧹 WIP is dropping");
2094
2095 while let Some(frame) = self.frames.pop() {
2096 self.track(frame);
2097 }
2098
2099 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
2100 trace!("No root found, we probably built already");
2101 return;
2102 };
2103
2104 let root_id = *root_id;
2105 let root_istate = self.istates.remove(&root_id).unwrap();
2106 let root = Frame::recompose(root_id, root_istate);
2107 let mut to_clean = vec![root];
2108
2109 let mut _root_guard: Option<Guard> = None;
2110
2111 while let Some(mut frame) = to_clean.pop() {
2112 trace!(
2113 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
2114 frame.shape.blue(),
2115 frame.data.as_byte_ptr(),
2116 frame.istate.flags.bright_magenta(),
2117 frame.istate.mode.yellow(),
2118 if frame.is_fully_initialized() {
2119 "✅"
2120 } else {
2121 "❌"
2122 }
2123 );
2124
2125 if frame.istate.flags.contains(FrameFlags::MOVED) {
2126 trace!(
2127 "{}",
2128 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
2129 );
2130 continue;
2131 }
2132
2133 match frame.shape.def {
2134 Def::Struct(sd) => {
2135 if frame.is_fully_initialized() {
2136 trace!(
2137 "Dropping fully initialized struct: {} at {:p}",
2138 frame.shape.green(),
2139 frame.data.as_byte_ptr()
2140 );
2141 let frame = self.evict_tree(frame);
2142 unsafe { frame.drop_and_dealloc_if_needed() };
2143 } else {
2144 let num_fields = sd.fields.len();
2145 trace!(
2146 "De-initializing struct {} at {:p} field-by-field ({} fields)",
2147 frame.shape.yellow(),
2148 frame.data.as_byte_ptr(),
2149 num_fields.to_string().bright_cyan()
2150 );
2151 for i in 0..num_fields {
2152 if frame.istate.fields.has(i) {
2153 let field = sd.fields[i];
2154 let field_shape = field.shape();
2155 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
2156 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2157 trace!(
2158 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
2159 i.to_string().bright_cyan(),
2160 field.name.bright_blue(),
2161 frame.shape.blue(),
2162 field_shape.green(),
2163 field_ptr.as_byte_ptr()
2164 );
2165 let istate = self.istates.remove(&field_id).unwrap();
2166 let field_frame = Frame::recompose(field_id, istate);
2167 to_clean.push(field_frame);
2168 } else {
2169 trace!(
2170 "Field #{} '{}' of {} was NOT initialized, skipping",
2171 i.to_string().bright_cyan(),
2172 sd.fields[i].name.bright_red(),
2173 frame.shape.red()
2174 );
2175 }
2176 }
2177
2178 if frame.istate.mode == FrameMode::Root {
2180 if let Ok(layout) = frame.shape.layout.sized_layout() {
2181 _root_guard = Some(Guard {
2182 ptr: frame.data.as_mut_byte_ptr(),
2183 layout,
2184 });
2185 }
2186 }
2187 }
2188 }
2189 Def::Enum(_ed) => {
2190 trace!(
2191 "{}",
2192 format_args!(
2193 "TODO: handle enum deallocation for {} at {:p}",
2194 frame.shape.yellow(),
2195 frame.data.as_byte_ptr()
2196 )
2197 .magenta()
2198 );
2199
2200 if frame.istate.mode == FrameMode::Root {
2202 if let Ok(layout) = frame.shape.layout.sized_layout() {
2203 _root_guard = Some(Guard {
2204 ptr: frame.data.as_mut_byte_ptr(),
2205 layout,
2206 });
2207 }
2208 }
2209 }
2210 Def::Array(_)
2211 | Def::Slice(_)
2212 | Def::List(_)
2213 | Def::Map(_)
2214 | Def::SmartPointer(_)
2215 | Def::Scalar(_)
2216 | Def::FunctionPointer(_)
2217 | Def::Option(_) => {
2218 trace!(
2219 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
2220 frame.shape.cyan(),
2221 frame.shape.def,
2222 frame.istate.mode.yellow(),
2223 frame.data.as_byte_ptr(),
2224 );
2225
2226 if frame.is_fully_initialized() {
2227 unsafe { frame.drop_and_dealloc_if_needed() }
2228 } else {
2229 frame.dealloc_if_needed();
2230 }
2231 }
2232 _ => {}
2233 }
2234 }
2235
2236 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
2238 for frame_id in all_ids.drain(..) {
2239 let frame_istate = self.istates.remove(&frame_id).unwrap();
2240
2241 trace!(
2242 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
2243 frame_id.shape.cyan(),
2244 frame_id.ptr,
2245 frame_istate.mode.yellow()
2246 );
2247 let mut frame = Frame::recompose(frame_id, frame_istate);
2248
2249 if frame.is_fully_initialized() {
2250 trace!("It's fully initialized, we can drop it");
2251 unsafe { frame.drop_and_dealloc_if_needed() };
2252 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
2253 trace!("Not initialized but allocated, let's free it");
2254 frame.dealloc_if_needed();
2255 }
2256 }
2257 }
2258}