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, ScalarAffinity, Shape,
14 Variant,
15};
16use flat_map::FlatMap;
17
18use alloc::string::String;
19
20mod iset;
21pub use iset::*;
22
23mod put_f64;
24
25mod enum_;
26mod flat_map;
27
28mod heap_value;
29pub use heap_value::*;
30
31fn def_kind(def: &Def) -> &'static str {
32 match def {
33 Def::Scalar(_) => "scalar",
34 Def::Struct(_) => "struct",
35 Def::Map(_) => "map",
36 Def::List(_) => "list",
37 Def::Enum(_) => "enum",
38 Def::Option(_) => "option",
39 Def::SmartPointer(_) => "smart_ptr",
40 _ => "other",
41 }
42}
43
44pub struct Frame {
46 data: PtrUninit<'static>,
48
49 shape: &'static Shape,
51
52 field_index_in_parent: Option<usize>,
55
56 istate: IState,
60}
61
62impl Frame {
63 fn recompose(id: ValueId, istate: IState) -> Self {
65 Frame {
66 data: PtrUninit::new(id.ptr as *mut u8),
67 shape: id.shape,
68 field_index_in_parent: None,
69 istate,
70 }
71 }
72
73 fn dealloc_if_needed(&mut self) {
75 if self.istate.flags.contains(FrameFlags::ALLOCATED) {
76 trace!(
77 "[{}] {:p} => deallocating {}",
78 self.istate.depth,
79 self.data.as_mut_byte_ptr().magenta(),
80 self.shape.green(),
81 );
82 match self.shape.layout {
83 facet_core::ShapeLayout::Sized(layout) => {
84 if layout.size() != 0 {
85 unsafe {
86 alloc::alloc::dealloc(self.data.as_mut_byte_ptr(), layout);
87 }
88 }
89 }
90 facet_core::ShapeLayout::Unsized => unimplemented!(),
91 }
92 self.istate.flags.remove(FrameFlags::ALLOCATED);
93 } else {
94 trace!(
95 "[{}] {:p} => NOT deallocating {} (not ALLOCATED)",
96 self.istate.depth,
97 self.data.as_mut_byte_ptr().magenta(),
98 self.shape.green(),
99 );
100 }
101 }
102}
103
104struct DisplayToDebug<T>(T);
105
106impl<T> fmt::Debug for DisplayToDebug<T>
107where
108 T: fmt::Display,
109{
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 fmt::Display::fmt(&self.0, f)
112 }
113}
114
115impl fmt::Debug for Frame {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.debug_struct("Frame")
118 .field("shape", &DisplayToDebug(&self.shape))
119 .field("kind", &def_kind(&self.shape.def))
120 .field("index", &self.field_index_in_parent)
121 .field("mode", &self.istate.mode)
122 .field("id", &self.id())
123 .finish()
124 }
125}
126
127impl Frame {
128 fn id(&self) -> ValueId {
130 ValueId::new(self.shape, self.data.as_byte_ptr())
131 }
132
133 fn is_fully_initialized(&self) -> bool {
135 match self.shape.def {
136 Def::Struct(sd) => self.istate.fields.are_all_set(sd.fields.len()),
137 Def::Enum(_) => match self.istate.variant.as_ref() {
138 None => false,
139 Some(v) => self.istate.fields.are_all_set(v.data.fields.len()),
140 },
141 _ => self.istate.fields.are_all_set(1),
142 }
143 }
144
145 unsafe fn drop_and_dealloc_if_needed(mut self) {
147 trace!(
148 "[Frame::drop] Dropping frame for shape {} at {:p}",
149 self.shape.blue(),
150 self.data.as_byte_ptr()
151 );
152 if let Some(drop_in_place) = self.shape.vtable.drop_in_place {
153 unsafe {
154 trace!(
155 "[Frame::drop] Invoking drop_in_place for shape {} at {:p}",
156 self.shape.green(),
157 self.data.as_byte_ptr()
158 );
159 drop_in_place(self.data.assume_init());
160 }
161 } else {
162 trace!(
163 "[Frame::drop] No drop_in_place function for shape {}",
164 self.shape.blue(),
165 );
166 }
167 self.dealloc_if_needed();
168 }
169
170 unsafe fn mark_fully_initialized(&mut self) {
172 match self.shape.def {
173 Def::Struct(sd) => {
174 self.istate.fields = ISet::all(sd.fields);
175 }
176 Def::Enum(_) => {
177 if let Some(variant) = &self.istate.variant {
178 self.istate.fields = ISet::all(variant.data.fields);
179 }
180 }
181 _ => {
182 self.istate.fields.set(0);
183 }
184 }
185 }
186}
187
188struct IState {
190 variant: Option<Variant>,
192
193 fields: ISet,
195
196 depth: usize,
198
199 mode: FrameMode,
201
202 flags: FrameFlags,
204
205 list_index: Option<usize>,
207
208 #[allow(dead_code)]
210 map_key: Option<String>,
211}
212
213bitflags! {
214 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
216 pub struct FrameFlags: u64 {
217 const EMPTY = 0;
219
220 const ALLOCATED = 1 << 0;
222
223 const MOVED = 1 << 1;
227 }
228
229 }
231
232impl IState {
233 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
235 Self {
236 variant: None,
237 fields: Default::default(),
238 depth,
239 mode,
240 flags,
241 list_index: None,
242 map_key: None,
243 }
244 }
245
246 #[allow(dead_code)]
248 pub fn with_list_index(mut self, index: usize) -> Self {
249 self.list_index = Some(index);
250 self
251 }
252
253 #[allow(dead_code)]
255 pub fn with_map_key(mut self, key: String) -> Self {
256 self.map_key = Some(key);
257 self
258 }
259}
260
261#[derive(Debug, Clone, Copy, PartialEq, Eq)]
263pub enum FrameMode {
264 Root,
266 Field,
268 ListElement,
270 MapKey,
272 MapValue {
274 index: usize,
276 },
277 OptionSome,
279 OptionNone,
282}
283
284pub struct Wip<'facet_lifetime> {
286 frames: alloc::vec::Vec<Frame>,
288
289 istates: FlatMap<ValueId, IState>,
291
292 invariant: PhantomData<fn(&'facet_lifetime ()) -> &'facet_lifetime ()>,
293}
294
295impl<'facet_lifetime> Wip<'facet_lifetime> {
296 pub fn put_peek(
298 self,
299 peek: crate::Peek<'_, 'facet_lifetime>,
300 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
301 self.put_shape(peek.data, peek.shape)
302 }
303
304 pub fn frames_count(&self) -> usize {
306 self.frames.len()
307 }
308
309 pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
311 let data = shape
312 .allocate()
313 .map_err(|_| ReflectError::Unsized { shape })?;
314 Ok(Self {
315 frames: alloc::vec![Frame {
316 data,
317 shape,
318 field_index_in_parent: None,
319 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
320 }],
321 istates: Default::default(),
322 invariant: PhantomData,
323 })
324 }
325
326 pub fn alloc<S: Facet<'facet_lifetime>>() -> Result<Self, ReflectError> {
328 Self::alloc_shape(S::SHAPE)
329 }
330
331 fn track(&mut self, frame: Frame) {
332 if frame.istate.flags.contains(FrameFlags::MOVED) {
338 return;
340 }
341
342 self.istates.insert(frame.id(), frame.istate);
343 }
344
345 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame) {
346 unsafe fn mark_subtree_moved(wip: &mut Wip, id: ValueId) {
349 unsafe {
351 if let Some(mut istate) = wip.istates.remove(&id) {
353 istate.flags.insert(FrameFlags::MOVED);
355
356 match id.shape.def {
358 Def::Struct(sd) => {
359 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
360 for field in sd.fields.iter() {
361 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
362 let field_id =
363 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
364 mark_subtree_moved(wip, field_id);
366 }
367 }
368 Def::Enum(_) => {
369 if let Some(variant) = &istate.variant {
371 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
372 for field in variant.data.fields.iter() {
373 let field_ptr_uninit =
374 container_ptr.field_uninit_at(field.offset);
375 let field_id =
376 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
377 mark_subtree_moved(wip, field_id);
379 }
380 }
381 }
382 _ => {}
386 }
387
388 if istate.flags.contains(FrameFlags::ALLOCATED) {
391 let mut temp_frame = Frame::recompose(id, istate);
393 temp_frame.dealloc_if_needed();
394 }
395 }
396 }
398 }
399
400 unsafe {
403 let frame_id = frame.id();
405
406 let variant_opt = frame.istate.variant;
408
409 frame.istate.flags.insert(FrameFlags::MOVED);
411 ISet::clear(&mut frame.istate.fields);
412
413 match frame.shape.def {
416 Def::Struct(sd) => {
417 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
418 for field in sd.fields.iter() {
419 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
420 let field_id = ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
421 mark_subtree_moved(self, field_id);
422 }
423 }
424 Def::Enum(_) => {
425 if let Some(variant) = &variant_opt {
427 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
428 for field in variant.data.fields.iter() {
429 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
430 let field_id =
431 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
432 mark_subtree_moved(self, field_id);
433 }
434 }
435 }
436 _ => {}
438 }
439
440 frame.istate.variant = None;
442
443 self.istates.remove(&frame_id);
445
446 if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
448 frame.dealloc_if_needed();
449 }
450 }
451 }
452
453 pub fn shape(&self) -> &'static Shape {
455 self.frames.last().expect("must have frames left").shape
456 }
457
458 pub fn innermost_shape(&self) -> &'static Shape {
462 let mut current_shape = self.shape();
463
464 while let Some(inner_fn) = current_shape.inner {
466 current_shape = inner_fn();
467 }
468
469 current_shape
470 }
471
472 pub fn in_option(&self) -> bool {
474 let Some(frame) = self.frames.last() else {
475 return false;
476 };
477 matches!(frame.istate.mode, FrameMode::OptionSome)
478 }
479
480 pub fn mode(&self) -> FrameMode {
482 self.frames.last().unwrap().istate.mode
483 }
484
485 pub fn build(mut self) -> Result<HeapValue<'facet_lifetime>, ReflectError> {
487 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
488
489 if self.frames.is_empty() {
491 panic!("No frames in WIP during build: stack is empty (you popped too much)");
492 }
493 if self.frames.len() != 1 {
494 panic!(
495 "You must pop frames so that only the root frame remains before calling build (frames left: {})",
496 self.frames.len()
497 );
498 }
499
500 let root_frame = &self.frames[0];
502
503 enum FrameRef {
504 Root,
505 ById(ValueId),
506 }
507 let mut to_check = alloc::vec![FrameRef::Root];
508
509 while let Some(fr) = to_check.pop() {
511 let (id, istate) = match fr {
512 FrameRef::Root => (root_frame.id(), &root_frame.istate),
513 FrameRef::ById(id) => {
514 let istate = self.istates.get(&id).unwrap();
516 (id, istate)
517 }
518 };
519
520 trace!(
521 "Checking shape {} at {:p}, flags={:?}, mode={:?}",
522 id.shape.blue(),
523 id.ptr,
524 istate.flags.bright_magenta(),
525 istate.mode,
526 );
527
528 if istate.flags.contains(FrameFlags::MOVED) {
530 trace!(
531 "{}",
532 "Frame was moved out of, skipping initialization check".yellow()
533 );
534 continue;
535 }
536
537 match id.shape.def {
539 Def::Struct(sd) => {
540 for i in 0..sd.fields.len() {
542 if !istate.fields.has(i) {
543 let field = &sd.fields[i];
544 return Err(ReflectError::UninitializedField {
545 shape: id.shape,
546 field_name: field.name,
547 });
548 }
549 }
550
551 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
552
553 #[allow(clippy::unused_enumerate_index)]
555 for (_i, field) in sd.fields.iter().enumerate() {
556 let field_shape = field.shape();
557 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
558 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
559
560 if self.istates.contains_key(&field_id) {
561 debug!(
562 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
563 _i.to_string().bright_cyan(),
564 field.name.bright_blue(),
565 id.shape.blue(),
566 field_shape.green(),
567 field_ptr.as_byte_ptr()
568 );
569 to_check.push(FrameRef::ById(field_id));
570 }
571 }
572 }
573 Def::Enum(_ed) => {
574 if let Some(variant) = &istate.variant {
575 for (i, field) in variant.data.fields.iter().enumerate() {
577 if !istate.fields.has(i) {
578 return Err(ReflectError::UninitializedEnumField {
579 shape: id.shape,
580 variant_name: variant.name,
581 field_name: field.name,
582 });
583 }
584 }
585
586 #[allow(clippy::unused_enumerate_index)]
588 for (_i, field) in variant.data.fields.iter().enumerate() {
589 let field_shape = field.shape();
590 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
591 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
593 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
594
595 if self.istates.contains_key(&field_id) {
596 debug!(
597 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
598 _i.to_string().bright_cyan(),
599 field.name.bright_blue(),
600 variant.name.yellow(),
601 id.shape.blue(),
602 field_shape.green(),
603 field_ptr.as_byte_ptr()
604 );
605 to_check.push(FrameRef::ById(field_id));
606 }
607 }
608 } else {
609 debug!("Found no variant selected for enum");
611 return Err(ReflectError::NoVariantSelected { shape: id.shape });
612 }
613 }
614 Def::List(_)
618 | Def::Map(_)
619 | Def::Option(_)
620 | Def::Scalar(_)
621 | Def::FunctionPointer(_)
622 | Def::SmartPointer(_)
623 | Def::Array(_)
624 | Def::Slice(_) => {
625 if !istate.fields.are_all_set(1) {
626 match istate.mode {
628 FrameMode::OptionNone => {
629 debug!("Found uninitialized value (option none)");
631 return Err(ReflectError::UninitializedValue { shape: id.shape });
632 }
633 _ => {
635 debug!("Found uninitialized value (list/map/option/etc.)");
636 return Err(ReflectError::UninitializedValue { shape: id.shape });
637 }
638 }
639 }
640 }
648 _ => {
650 if !istate.fields.are_all_set(1) {
652 debug!("Found uninitialized value (other)");
653 return Err(ReflectError::UninitializedValue { shape: id.shape });
654 }
655 }
656 }
657 }
658
659 debug!("All reachable frames checked and initialized.");
661
662 let root_shape = root_frame.shape;
665 let root_data = unsafe { root_frame.data.assume_init() };
666 if let Some(invariant_fn) = root_shape.vtable.invariants {
667 debug!(
668 "Checking invariants for root shape {} at {:p}",
669 root_shape.green(),
670 root_data.as_byte_ptr()
671 );
672 if !unsafe { invariant_fn(PtrConst::new(root_data.as_byte_ptr())) } {
673 return Err(ReflectError::InvariantViolation {
674 invariant: "Custom validation function returned false",
675 });
676 }
677 } else {
678 debug!(
679 "No invariants to check for root shape {}",
680 root_shape.blue()
681 );
682 }
683
684 {
686 FlatMap::clear(&mut self.istates);
687 self.frames.clear();
688 }
689
690 let guard = Guard {
692 ptr: root_data.as_mut_byte_ptr(),
693 layout: match root_shape.layout {
694 facet_core::ShapeLayout::Sized(layout) => layout,
695 facet_core::ShapeLayout::Unsized => panic!("Unsized layout not supported"),
696 },
697 };
698
699 Ok(HeapValue {
700 guard: Some(guard),
701 shape: root_shape,
702 phantom: PhantomData,
703 })
704 }
705
706 pub fn field(mut self, index: usize) -> Result<Self, ReflectError> {
718 let frame = self.frames.last_mut().unwrap();
719 let shape = frame.shape;
720
721 let (field, field_offset) = match shape.def {
722 Def::Struct(def) => {
723 if index >= def.fields.len() {
724 return Err(ReflectError::FieldError {
725 shape,
726 field_error: FieldError::NoSuchField,
727 });
728 }
729 let field = &def.fields[index];
730 (field, field.offset)
731 }
732 Def::Enum(_) => {
733 let Some(variant) = frame.istate.variant.as_ref() else {
734 return Err(ReflectError::OperationFailed {
735 shape,
736 operation: "tried to access a field but no variant was selected",
737 });
738 };
739
740 if index >= variant.data.fields.len() {
741 return Err(ReflectError::FieldError {
742 shape,
743 field_error: FieldError::NoSuchField,
744 });
745 }
746
747 let field = &variant.data.fields[index];
748 (field, field.offset)
749 }
750 _ => {
751 return Err(ReflectError::WasNotA {
752 expected: "struct or enum",
753 actual: shape,
754 });
755 }
756 };
757
758 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
759
760 let mut frame = Frame {
761 data: field_data,
762 shape: field.shape(),
763 field_index_in_parent: Some(index),
764 istate: IState::new(self.frames.len(), FrameMode::Field, FrameFlags::EMPTY),
766 };
767 debug!(
768 "[{}] Selecting field {} ({}#{}) of {}",
769 self.frames.len(),
770 field.name.blue(),
771 field.shape().green(),
772 index.yellow(),
773 shape.blue(),
774 );
775 if let Some(iset) = self.istates.remove(&frame.id()) {
776 trace!(
777 "[{}] Restoring saved state for {} (istate.mode = {:?}, istate.fields = {:?}, istate.flags = {:?}, istate.depth = {:?})",
778 self.frames.len(),
779 frame.id().shape.blue(),
780 iset.mode,
781 iset.fields,
782 iset.flags,
783 iset.depth
784 );
785 frame.istate = iset;
786 } else {
787 trace!(
788 "[{}] no saved state for field {} ({}#{}) of {}",
789 self.frames.len(),
790 field.name.blue(),
791 field.shape().green(),
792 index.yellow(),
793 shape.blue(),
794 );
795 }
796 self.frames.push(frame);
797 Ok(self)
798 }
799
800 pub fn field_index(&self, name: &str) -> Option<usize> {
812 fn find_field_index(fields: &'static [facet_core::Field], name: &str) -> Option<usize> {
813 fields.iter().position(|f| f.name == name)
814 }
815
816 let frame = self.frames.last()?;
817 match frame.shape.def {
818 Def::Struct(def) => find_field_index(def.fields, name),
819 Def::Enum(_) => {
820 let variant = frame.istate.variant.as_ref()?;
821 find_field_index(variant.data.fields, name)
822 }
823 _ => None,
824 }
825 }
826
827 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
839 let frame = self.frames.last().unwrap();
840 let shape = frame.shape;
841
842 if let Def::Enum(_) = shape.def {
844 if frame.istate.variant.is_none() {
845 return Err(ReflectError::OperationFailed {
846 shape,
847 operation: "tried to access a field by name but no variant was selected",
848 });
849 }
850 }
851
852 let index = self.field_index(name).ok_or(ReflectError::FieldError {
853 shape,
854 field_error: FieldError::NoSuchField,
855 })?;
856
857 self.field(index)
858 }
859
860 pub fn put<T: Facet<'facet_lifetime>>(
871 self,
872 t: T,
873 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
874 let shape = T::SHAPE;
875 let ptr_const = PtrConst::new(&t as *const T as *const u8);
876 let res = self.put_shape(ptr_const, shape);
877 core::mem::forget(t); res
879 }
880
881 pub fn try_put<T: Facet<'facet_lifetime>>(
892 self,
893 t: T,
894 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
895 let shape = T::SHAPE;
896 let ptr_const = PtrConst::new(&t as *const T as *const u8);
897 let res = self.put_shape(ptr_const, shape);
898 core::mem::forget(t); res
900 }
901
902 pub fn put_shape(
904 mut self,
905 src: PtrConst<'_>,
906 src_shape: &'static Shape,
907 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
908 let Some(frame) = self.frames.last_mut() else {
909 return Err(ReflectError::OperationFailed {
910 shape: src_shape,
911 operation: "tried to put a value but there was no frame to put into",
912 });
913 };
914
915 if frame.shape != src_shape {
917 trace!(
918 "Trying to put a {} into a {}",
919 src_shape.yellow(),
920 frame.shape.magenta()
921 );
922
923 if let Some(inner_fn) = frame.shape.inner {
925 let inner_shape = inner_fn();
927
928 if src_shape == inner_shape {
930 if let Some(try_from_fn) = frame.shape.vtable.try_from {
932 match unsafe { (try_from_fn)(src, src_shape, frame.data) } {
933 Ok(_) => {
934 unsafe {
935 frame.mark_fully_initialized();
936 }
937
938 let shape = frame.shape;
939 let index = frame.field_index_in_parent;
940
941 self.mark_field_as_initialized(shape, index)?;
943
944 debug!(
945 "[{}] Just put a {} value into transparent type {}",
946 self.frames.len(),
947 src_shape.green(),
948 shape.blue()
949 );
950
951 return Ok(self);
952 }
953 Err(e) => {
954 return Err(ReflectError::TryFromError {
955 inner: e,
956 src_shape,
957 dst_shape: frame.shape,
958 });
959 }
960 }
961 } else {
962 debug!(
964 "No try_from_inner function for transparent type, falling back to TryFrom"
965 );
966 }
967 }
968 }
969
970 if let Some(try_from) = frame.shape.vtable.try_from {
972 match unsafe { try_from(src, src_shape, frame.data) } {
973 Ok(_) => {
974 unsafe {
975 frame.mark_fully_initialized();
976 }
977
978 let shape = frame.shape;
979 let index = frame.field_index_in_parent;
980
981 self.mark_field_as_initialized(shape, index)?;
983
984 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
985
986 return Ok(self);
987 }
988 Err(e) => {
989 return Err(ReflectError::TryFromError {
990 inner: e,
991 src_shape,
992 dst_shape: frame.shape,
993 });
994 }
995 }
996 }
997
998 if let Def::Option(od) = frame.shape.def {
1001 if od.t() == src_shape {
1003 debug!("Putting into an Option<T>!");
1004 if frame.istate.fields.is_any_set() {
1005 let data = unsafe { frame.data.assume_init() };
1006 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
1007 } else {
1008 let data = frame.data;
1009 unsafe { (od.vtable.init_some_fn)(data, src) };
1010 }
1011 unsafe {
1012 frame.mark_fully_initialized();
1013 }
1014
1015 let shape = frame.shape;
1016 let index = frame.field_index_in_parent;
1017
1018 self.mark_field_as_initialized(shape, index)?;
1020
1021 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1022
1023 return Ok(self);
1024 }
1025 }
1026
1027 if let Def::Struct(sd) = frame.shape.def {
1031 for (i, field) in sd.fields.iter().enumerate() {
1033 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1034 debug!(
1035 "Found uninitialized field {} with matching type {}",
1036 i.to_string().blue(),
1037 src_shape.green()
1038 );
1039
1040 unsafe {
1042 let field_data = frame.data.field_uninit_at(field.offset);
1043 field_data.copy_from(src, field.shape()).map_err(|_| {
1044 ReflectError::Unsized {
1045 shape: field.shape(),
1046 }
1047 })?;
1048 frame.istate.fields.set(i);
1049 }
1050
1051 let shape = frame.shape;
1052 let index = frame.field_index_in_parent;
1053
1054 if frame.is_fully_initialized() {
1056 self.mark_field_as_initialized(shape, index)?;
1057 }
1058
1059 debug!(
1060 "[{}] Put a {} value into field {} of {}",
1061 self.frames.len(),
1062 src_shape.green(),
1063 i.to_string().blue(),
1064 shape.green()
1065 );
1066
1067 return Ok(self);
1068 }
1069 }
1070 }
1071
1072 if let Def::Enum(_) = frame.shape.def {
1075 if let Some(variant) = &frame.istate.variant {
1077 for (i, field) in variant.data.fields.iter().enumerate() {
1079 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1080 debug!(
1081 "Found uninitialized field {} in enum variant '{}' with matching type {}",
1082 i.to_string().blue(),
1083 variant.name.bright_yellow(),
1084 src_shape.green()
1085 );
1086
1087 unsafe {
1089 let field_data = frame.data.field_uninit_at(field.offset);
1090 field_data.copy_from(src, field.shape()).map_err(|_| {
1091 ReflectError::Unsized {
1092 shape: field.shape(),
1093 }
1094 })?;
1095 frame.istate.fields.set(i);
1096 }
1097
1098 let shape = frame.shape;
1099 let index = frame.field_index_in_parent;
1100
1101 #[allow(unused)]
1102 let variant_name = variant.name;
1103
1104 if frame.is_fully_initialized() {
1106 self.mark_field_as_initialized(shape, index)?;
1107 }
1108
1109 debug!(
1110 "[{}] Put a {} value into field {} of variant '{}' in enum {}",
1111 self.frames.len(),
1112 src_shape.green(),
1113 i.to_string().blue(),
1114 variant_name.bright_yellow(),
1115 shape.green()
1116 );
1117
1118 return Ok(self);
1119 }
1120 }
1121 }
1122 }
1123
1124 return Err(ReflectError::WrongShape {
1125 expected: frame.shape,
1126 actual: src_shape,
1127 });
1128 }
1129
1130 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
1132 debug!("De-initializing partially initialized {:?}", frame.yellow());
1133
1134 match frame.shape.def {
1135 Def::Struct(sd) => {
1136 for (i, field) in sd.fields.iter().enumerate() {
1137 if frame.istate.fields.has(i) {
1138 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1139 unsafe {
1140 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
1141 drop_fn(PtrMut::new(field_ptr));
1142 }
1143 }
1144 }
1145 }
1146 }
1147 Def::Enum(_) => {
1148 if let Some(variant) = &frame.istate.variant {
1149 for (i, field) in variant.data.fields.iter().enumerate() {
1150 if frame.istate.fields.has(i) {
1151 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1152 unsafe {
1153 let field_ptr =
1154 frame.data.as_mut_byte_ptr().add(field.offset);
1155 drop_fn(PtrMut::new(field_ptr));
1156 }
1157 }
1158 }
1159 }
1160 }
1161 }
1162 _ => {
1163 if frame.istate.fields.is_any_set() {
1165 debug!("Scalar type was set...");
1166 if let Some(drop_fn) = frame.shape.vtable.drop_in_place {
1167 debug!("And it has a drop fn, dropping now!");
1168 unsafe {
1169 drop_fn(frame.data.assume_init());
1170 }
1171 }
1172 }
1173 }
1174 }
1175
1176 frame.istate.variant = None;
1178 ISet::clear(&mut frame.istate.fields);
1179 }
1180
1181 unsafe {
1182 frame
1184 .data
1185 .copy_from(src, frame.shape)
1186 .map_err(|_| ReflectError::Unsized { shape: frame.shape })?;
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 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1197
1198 Ok(self)
1199 }
1200
1201 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
1203 let Some(frame) = self.frames.last_mut() else {
1204 return Err(ReflectError::OperationFailed {
1205 shape: <()>::SHAPE,
1206 operation: "tried to parse value but there was no frame",
1207 });
1208 };
1209
1210 let shape = frame.shape;
1211 let index = frame.field_index_in_parent;
1212
1213 let Some(parse_fn) = frame.shape.vtable.parse else {
1214 return Err(ReflectError::OperationFailed {
1215 shape: frame.shape,
1216 operation: "type does not implement Parse",
1217 });
1218 };
1219 match unsafe { (parse_fn)(s, frame.data) } {
1220 Ok(_res) => {
1221 unsafe {
1222 frame.mark_fully_initialized();
1223 }
1224
1225 self.mark_field_as_initialized(shape, index)?;
1227
1228 Ok(self)
1229 }
1230 Err(_) => Err(ReflectError::OperationFailed {
1231 shape,
1232 operation: "parsing",
1233 }),
1234 }
1235 }
1236
1237 pub fn put_from_fn(mut self, default_in_place: DefaultInPlaceFn) -> Result<Self, ReflectError> {
1239 let Some(frame) = self.frames.last_mut() else {
1240 return Err(ReflectError::OperationFailed {
1241 shape: <()>::SHAPE,
1242 operation: "tried to put value from fn but there was no frame",
1243 });
1244 };
1245
1246 unsafe {
1247 default_in_place(frame.data);
1248 frame.mark_fully_initialized();
1249 }
1250
1251 let shape = frame.shape;
1252 let index = frame.field_index_in_parent;
1253
1254 self.mark_field_as_initialized(shape, index)?;
1256
1257 Ok(self)
1258 }
1259
1260 pub fn put_default(self) -> Result<Self, ReflectError> {
1262 let Some(frame) = self.frames.last() else {
1263 return Err(ReflectError::OperationFailed {
1264 shape: <()>::SHAPE,
1265 operation: "tried to put default value but there was no frame",
1266 });
1267 };
1268
1269 let vtable = frame.shape.vtable;
1270 let Some(default_in_place) = vtable.default_in_place else {
1271 return Err(ReflectError::OperationFailed {
1272 shape: frame.shape,
1273 operation: "type does not implement Default",
1274 });
1275 };
1276
1277 self.put_from_fn(default_in_place)
1278 }
1279
1280 fn mark_field_as_initialized(
1282 &mut self,
1283 shape: &'static Shape,
1284 index: Option<usize>,
1285 ) -> Result<(), ReflectError> {
1286 if let Some(index) = index {
1287 let parent_index = self.frames.len().saturating_sub(2);
1288 #[cfg(feature = "log")]
1289 let num_frames = self.frames.len();
1290 let Some(parent) = self.frames.get_mut(parent_index) else {
1291 return Err(ReflectError::OperationFailed {
1292 shape,
1293 operation: "was supposed to mark a field as initialized, but there was no parent frame",
1294 });
1295 };
1296 #[cfg(feature = "log")]
1297 let parent_shape = parent.shape;
1298 trace!(
1299 "[{}] {}.{} initialized with {}",
1300 num_frames,
1301 parent_shape.blue(),
1302 index.yellow(),
1303 shape.green()
1304 );
1305
1306 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
1307 return Err(ReflectError::OperationFailed {
1308 shape,
1309 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
1310 });
1311 }
1312
1313 if parent.istate.fields.has(index) {
1314 return Err(ReflectError::OperationFailed {
1315 shape,
1316 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
1317 });
1318 }
1319
1320 parent.istate.fields.set(index);
1321 }
1322 Ok(())
1323 }
1324
1325 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
1327 let frame = self.frames.last().unwrap();
1328 let shape = frame.shape;
1329
1330 match shape.def {
1331 Def::List(list_def) => Ok(list_def.t()),
1332 _ => Err(ReflectError::WasNotA {
1333 expected: "list or array",
1334 actual: shape,
1335 }),
1336 }
1337 }
1338
1339 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
1341 let frame = self.frames.last().unwrap();
1342 let shape = frame.shape;
1343
1344 match shape.def {
1345 Def::Map(map_def) => Ok(map_def.k),
1346 _ => Err(ReflectError::WasNotA {
1347 expected: "map",
1348 actual: shape,
1349 }),
1350 }
1351 }
1352
1353 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
1355 let Some(frame) = self.frames.last_mut() else {
1356 return Err(ReflectError::OperationFailed {
1357 shape: <()>::SHAPE,
1358 operation: "tried to create empty list but there was no frame",
1359 });
1360 };
1361
1362 if !matches!(frame.shape.def, Def::List(_)) {
1363 return Err(ReflectError::WasNotA {
1364 expected: "list or array",
1365 actual: frame.shape,
1366 });
1367 }
1368
1369 let vtable = frame.shape.vtable;
1370
1371 let Some(default_in_place) = vtable.default_in_place else {
1373 return Err(ReflectError::OperationFailed {
1374 shape: frame.shape,
1375 operation: "list type does not implement Default",
1376 });
1377 };
1378
1379 unsafe {
1380 default_in_place(frame.data);
1381 frame.mark_fully_initialized();
1382 }
1383
1384 let shape = frame.shape;
1385 let index = frame.field_index_in_parent;
1386
1387 self.mark_field_as_initialized(shape, index)?;
1389
1390 Ok(self)
1391 }
1392
1393 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1395 let Some(frame) = self.frames.last_mut() else {
1396 return Err(ReflectError::OperationFailed {
1397 shape: <()>::SHAPE,
1398 operation: "tried to create empty map but there was no frame",
1399 });
1400 };
1401
1402 if !matches!(frame.shape.def, Def::Map(_)) {
1403 return Err(ReflectError::WasNotA {
1404 expected: "map or hash map",
1405 actual: frame.shape,
1406 });
1407 }
1408
1409 let vtable = frame.shape.vtable;
1410
1411 let Some(default_in_place) = vtable.default_in_place else {
1413 return Err(ReflectError::OperationFailed {
1414 shape: frame.shape,
1415 operation: "map type does not implement Default",
1416 });
1417 };
1418
1419 unsafe {
1420 default_in_place(frame.data);
1421 frame.mark_fully_initialized();
1422 }
1423
1424 let shape = frame.shape;
1425 let index = frame.field_index_in_parent;
1426
1427 self.mark_field_as_initialized(shape, index)?;
1429
1430 Ok(self)
1431 }
1432
1433 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1438 let Some(frame) = self.frames.last_mut() else {
1439 return Err(ReflectError::OperationFailed {
1440 shape: <()>::SHAPE,
1441 operation: "tried to begin pushback but there was no frame",
1442 });
1443 };
1444
1445 let is_list = matches!(frame.shape.def, Def::List(_));
1446 let is_tuple_struct_or_variant = match frame.shape.def {
1447 Def::Scalar(sd) => matches!(sd.affinity, ScalarAffinity::Empty(_)),
1448 Def::Struct(sd) => sd.kind == facet_core::StructKind::Tuple,
1449 Def::Enum(_) => {
1450 if let Some(variant) = &frame.istate.variant {
1452 variant.data.kind == facet_core::StructKind::Tuple
1453 } else {
1454 false }
1463 }
1464 _ => false,
1465 };
1466
1467 if !is_list && !is_tuple_struct_or_variant {
1468 return Err(ReflectError::WasNotA {
1469 expected: "list, array, or tuple-like struct/enum variant",
1470 actual: frame.shape,
1471 });
1472 }
1473
1474 if is_list {
1476 let vtable = frame.shape.vtable;
1477 if !frame.istate.fields.has(0) {
1479 let Some(default_in_place) = vtable.default_in_place else {
1480 return Err(ReflectError::OperationFailed {
1481 shape: frame.shape,
1482 operation: "list type does not implement Default, cannot begin pushback",
1483 });
1484 };
1485
1486 unsafe {
1487 default_in_place(frame.data);
1488 frame.istate.fields.set(0);
1490 }
1491 }
1492 }
1493 Ok(self)
1496 }
1497
1498 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1500 let Some(frame) = self.frames.last_mut() else {
1501 return Err(ReflectError::OperationFailed {
1502 shape: <()>::SHAPE,
1503 operation: "tried to begin map insertion but there was no frame",
1504 });
1505 };
1506
1507 if !matches!(frame.shape.def, Def::Map(_)) {
1508 return Err(ReflectError::WasNotA {
1509 expected: "map or hash map",
1510 actual: frame.shape,
1511 });
1512 }
1513
1514 let vtable = frame.shape.vtable;
1515
1516 if !frame.istate.fields.has(0) {
1518 let Some(default_in_place) = vtable.default_in_place else {
1519 return Err(ReflectError::OperationFailed {
1520 shape: frame.shape,
1521 operation: "map type does not implement Default",
1522 });
1523 };
1524
1525 unsafe {
1526 default_in_place(frame.data);
1527 frame.istate.fields.set(0);
1528 }
1529 }
1530
1531 Ok(self)
1532 }
1533
1534 pub fn push(mut self) -> Result<Self, ReflectError> {
1539 let frame_len = self.frames.len();
1541 let frame = self
1542 .frames
1543 .last_mut()
1544 .ok_or(ReflectError::OperationFailed {
1545 shape: <()>::SHAPE,
1546 operation: "tried to push but there was no frame",
1547 })?;
1548 let seq_shape = frame.shape;
1549
1550 let (element_shape, context_str): (&'static Shape, &'static str) = match seq_shape.def {
1552 Def::List(_) => {
1553 if !frame.istate.fields.has(0) {
1555 return self.begin_pushback()?.push();
1558 }
1559 let shape = self.element_shape()?;
1562 (shape, "list")
1563 }
1564
1565 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
1566 let field_index = {
1568 let next_idx = frame.istate.list_index.unwrap_or(0);
1570 frame.istate.list_index = Some(next_idx + 1);
1571 next_idx
1572 };
1573 if field_index >= sd.fields.len() {
1575 return Err(ReflectError::FieldError {
1576 shape: seq_shape,
1577 field_error: FieldError::NoSuchField, });
1579 }
1580 (sd.fields[field_index].shape(), "tuple struct")
1582 }
1583
1584 Def::Enum(_) => {
1585 let variant =
1587 frame
1588 .istate
1589 .variant
1590 .as_ref()
1591 .ok_or(ReflectError::OperationFailed {
1592 shape: seq_shape,
1593 operation: "tried to push onto enum but no variant was selected",
1594 })?;
1595 if variant.data.kind != facet_core::StructKind::Tuple {
1597 return Err(ReflectError::WasNotA {
1598 expected: "tuple-like enum variant",
1599 actual: seq_shape, });
1601 }
1602 let field_index = {
1604 let next_idx = frame.istate.list_index.unwrap_or(0);
1606 frame.istate.list_index = Some(next_idx + 1);
1607 next_idx
1608 };
1609 if field_index >= variant.data.fields.len() {
1611 return Err(ReflectError::FieldError {
1612 shape: seq_shape, field_error: FieldError::NoSuchField,
1614 });
1615 }
1616 (
1618 variant.data.fields[field_index].shape(),
1619 "tuple enum variant",
1620 )
1621 }
1622
1623 Def::Scalar(sd) if matches!(sd.affinity, ScalarAffinity::Empty(_)) => {
1624 return Err(ReflectError::OperationFailed {
1626 shape: seq_shape,
1627 operation: "cannot push elements to unit type ()",
1628 });
1629 }
1630
1631 _ => {
1632 return Err(ReflectError::WasNotA {
1634 expected: "list, array, tuple struct, or tuple enum variant",
1635 actual: seq_shape,
1636 });
1637 }
1638 };
1639
1640 let element_data = element_shape
1642 .allocate()
1643 .map_err(|_| ReflectError::Unsized {
1644 shape: element_shape,
1645 })?;
1646
1647 let element_frame = Frame {
1649 data: element_data,
1650 shape: element_shape,
1651 field_index_in_parent: None, istate: IState::new(
1653 frame_len, FrameMode::ListElement, FrameFlags::ALLOCATED,
1656 ),
1657 };
1658
1659 trace!(
1660 "[{}] Pushing element of type {} to {} {}",
1661 frame_len,
1662 element_shape.green(),
1663 context_str, seq_shape.blue(),
1665 );
1666 let _ = context_str;
1667
1668 self.frames.push(element_frame);
1669 Ok(self)
1670 }
1671
1672 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1674 let frame = self.frames.last().unwrap();
1676 let option_shape = frame.shape;
1677
1678 let Def::Option(option_def) = option_shape.def else {
1680 return Err(ReflectError::WasNotA {
1681 expected: "option",
1682 actual: option_shape,
1683 });
1684 };
1685
1686 let inner_shape = option_def.t();
1688
1689 let inner_data = inner_shape
1691 .allocate()
1692 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1693
1694 let inner_frame = Frame {
1696 data: inner_data,
1697 shape: inner_shape,
1698 field_index_in_parent: None,
1700 istate: IState::new(
1701 self.frames.len(),
1702 FrameMode::OptionSome,
1703 FrameFlags::ALLOCATED,
1705 ),
1706 };
1707
1708 trace!(
1709 "[{}] Pushing option frame for {}",
1710 self.frames.len(),
1711 option_shape.blue(),
1712 );
1713
1714 self.frames.push(inner_frame);
1715 Ok(self)
1716 }
1717
1718 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1728 let Some(frame) = self.frames.last_mut() else {
1730 return Err(ReflectError::OperationFailed {
1731 shape: <()>::SHAPE,
1732 operation: "tried to pop_some_push_none but there was no frame",
1733 });
1734 };
1735
1736 if frame.istate.mode != FrameMode::OptionSome {
1738 return Err(ReflectError::OperationFailed {
1739 shape: frame.shape,
1740 operation: "pop_some_push_none called, but frame was not in Option mode",
1741 });
1742 }
1743
1744 if frame.is_fully_initialized() {
1746 return Err(ReflectError::OperationFailed {
1747 shape: frame.shape,
1748 operation: "option frame already initialized, cannot pop_some_push_none",
1749 });
1750 }
1751
1752 frame.dealloc_if_needed();
1753
1754 let _frame = self.frames.pop().expect("frame already checked");
1756
1757 let parent_frame = self
1759 .frames
1760 .last_mut()
1761 .ok_or(ReflectError::OperationFailed {
1762 shape: <()>::SHAPE,
1763 operation: "tried to pop_some_push_none but there was no parent frame",
1764 })?;
1765
1766 unsafe {
1768 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1769 default_fn(parent_frame.data);
1770 } else {
1771 return Err(ReflectError::OperationFailed {
1772 shape: parent_frame.shape,
1773 operation: "option type does not implement Default",
1774 });
1775 }
1776 parent_frame.mark_fully_initialized();
1777 }
1778
1779 let Def::Option(od) = parent_frame.shape.def else {
1780 return Err(ReflectError::OperationFailed {
1781 shape: parent_frame.shape,
1782 operation: "pop_some_push_none and the parent isn't of type Option???",
1783 });
1784 };
1785
1786 let data = parent_frame.data;
1788
1789 let mut frame = Frame {
1790 data,
1791 shape: od.t(),
1792 field_index_in_parent: Some(0),
1793 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1794 };
1795 unsafe {
1796 frame.mark_fully_initialized();
1797 }
1798
1799 self.frames.push(frame);
1800
1801 Ok(self)
1802 }
1803
1804 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1809 let frame = self.frames.last().unwrap();
1811 let map_shape = frame.shape;
1812
1813 if !matches!(map_shape.def, Def::Map(_)) {
1814 return Err(ReflectError::WasNotA {
1815 expected: "map or hash map",
1816 actual: map_shape,
1817 });
1818 }
1819
1820 if !frame.istate.fields.has(0) {
1822 self = self.begin_map_insert()?;
1823 }
1824
1825 let key_shape = self.key_shape()?;
1827
1828 let key_data = key_shape
1830 .allocate()
1831 .map_err(|_| ReflectError::Unsized { shape: key_shape })?;
1832
1833 let key_frame = Frame {
1835 data: key_data,
1836 shape: key_shape,
1837 field_index_in_parent: None,
1838 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1839 };
1840
1841 trace!(
1842 "[{}] Pushing key of type {} for map {}",
1843 self.frames.len(),
1844 key_shape.green(),
1845 map_shape.blue(),
1846 );
1847
1848 self.frames.push(key_frame);
1849 Ok(self)
1850 }
1851
1852 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1857 trace!("Wants to push map value. Frames = ");
1858 #[cfg(feature = "log")]
1859 for (i, f) in self.frames.iter().enumerate() {
1860 trace!("Frame {}: {:?}", i, f);
1861 }
1862
1863 if self.frames.len() < 2 {
1865 return Err(ReflectError::OperationFailed {
1866 shape: <()>::SHAPE,
1867 operation: "tried to push map value but there was no key frame",
1868 });
1869 }
1870
1871 let key_frame_index = self.frames.len() - 1;
1873 let key_frame = &self.frames[key_frame_index];
1874
1875 match key_frame.istate.mode {
1877 FrameMode::MapKey => {} _ => {
1879 return Err(ReflectError::OperationFailed {
1880 shape: key_frame.shape,
1881 operation: "current frame is not a map key",
1882 });
1883 }
1884 }
1885
1886 if !key_frame.is_fully_initialized() {
1888 return Err(ReflectError::OperationFailed {
1889 shape: key_frame.shape,
1890 operation: "map key is not fully initialized",
1891 });
1892 }
1893
1894 let map_frame_index = self.frames.len() - 2;
1896 let map_frame = &self.frames[map_frame_index];
1897 let map_shape = map_frame.shape;
1898
1899 let Def::Map(map_def) = map_shape.def else {
1900 return Err(ReflectError::WasNotA {
1901 expected: "map",
1902 actual: map_frame.shape,
1903 });
1904 };
1905
1906 let value_shape = map_def.v;
1907
1908 let value_data = value_shape
1910 .allocate()
1911 .map_err(|_| ReflectError::Unsized { shape: value_shape })?;
1912
1913 let value_frame = Frame {
1915 data: value_data,
1916 shape: value_shape,
1917 field_index_in_parent: None,
1918 istate: IState::new(
1919 self.frames.len(),
1920 FrameMode::MapValue {
1921 index: key_frame_index,
1922 },
1923 FrameFlags::ALLOCATED,
1924 ),
1925 };
1926
1927 trace!(
1928 "[{}] Pushing value of type {} for map {} with key type {}",
1929 self.frames.len(),
1930 value_shape.green(),
1931 map_shape.blue(),
1932 key_frame.shape.yellow(),
1933 );
1934
1935 self.frames.push(value_frame);
1936 Ok(self)
1937 }
1938
1939 pub fn pop(mut self) -> Result<Self, ReflectError> {
1941 let frame = match self.pop_inner()? {
1942 Some(frame) => frame,
1943 None => {
1944 return Err(ReflectError::InvariantViolation {
1945 invariant: "No frame to pop — it was time to call build()",
1946 });
1947 }
1948 };
1949
1950 self.track(frame);
1951 Ok(self)
1952 }
1953
1954 fn pop_inner(&mut self) -> Result<Option<Frame>, ReflectError> {
1955 let mut frame = match self.frames.pop() {
1956 Some(f) => f,
1957 None => return Ok(None),
1958 };
1959 #[cfg(feature = "log")]
1960 let frame_shape = frame.shape;
1961
1962 let init = frame.is_fully_initialized();
1963 trace!(
1964 "[{}] {} popped, {} initialized",
1965 self.frames.len(),
1966 frame_shape.blue(),
1967 if init {
1968 "✅ fully".style(owo_colors::Style::new().green())
1969 } else {
1970 "🚧 partially".style(owo_colors::Style::new().red())
1971 }
1972 );
1973 if init {
1974 if let Some(parent) = self.frames.last_mut() {
1975 if let Some(index) = frame.field_index_in_parent {
1976 parent.istate.fields.set(index);
1977 }
1978 }
1979 }
1980
1981 match frame.istate.mode {
1983 FrameMode::ListElement => {
1985 if frame.is_fully_initialized() {
1986 #[cfg(feature = "log")]
1988 let frame_len = self.frames.len();
1989
1990 let parent_frame = self.frames.last_mut().unwrap();
1992 let parent_shape = parent_frame.shape;
1993
1994 match parent_shape.def {
1995 Def::List(list_def) => {
1997 let list_vtable = list_def.vtable;
1998 trace!(
1999 "[{}] Pushing element to list {}",
2000 frame_len,
2001 parent_shape.blue()
2002 );
2003 unsafe {
2004 (list_vtable.push)(
2005 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
2006 PtrMut::new(frame.data.as_mut_byte_ptr()),
2007 );
2008 self.mark_moved_out_of(&mut frame);
2009 }
2010 }
2011
2012 Def::Struct(sd)
2014 if sd.kind == facet_core::StructKind::Tuple && sd.fields.is_empty() =>
2015 {
2016 trace!(
2017 "[{}] Handling empty tuple struct unit type {}",
2018 frame_len,
2019 parent_shape.blue()
2020 );
2021 unsafe {
2023 parent_frame.mark_fully_initialized();
2024 }
2025 unsafe { self.mark_moved_out_of(&mut frame) };
2027 }
2028 Def::Scalar(s) if matches!(s.affinity, ScalarAffinity::Empty(_)) => {
2029 trace!(
2030 "[{}] Handling scalar empty unit type {}",
2031 frame_len,
2032 parent_shape.blue()
2033 );
2034 unsafe {
2036 parent_frame.mark_fully_initialized();
2037 self.mark_moved_out_of(&mut frame);
2038 }
2039 }
2040
2041 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
2043 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2045 let field_index = previous_index - 1; if field_index >= sd.fields.len() {
2048 panic!(
2049 "Field index {} out of bounds for tuple struct {} with {} fields",
2050 field_index,
2051 parent_shape,
2052 sd.fields.len()
2053 );
2054 }
2055
2056 let field = &sd.fields[field_index];
2057 trace!(
2058 "[{}] Setting tuple struct field {} ({}) of {}",
2059 frame_len,
2060 field_index.to_string().yellow(),
2061 field.name.bright_blue(),
2062 parent_shape.blue()
2063 );
2064
2065 unsafe {
2066 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2068 field_ptr
2069 .copy_from(
2070 PtrConst::new(frame.data.as_byte_ptr()),
2071 field.shape(),
2072 )
2073 .map_err(|_| ReflectError::Unsized {
2074 shape: field.shape(),
2075 })?; parent_frame.istate.fields.set(field_index);
2079
2080 self.mark_moved_out_of(&mut frame);
2082 }
2083 }
2084
2085 Def::Enum(_) => {
2087 let variant =
2089 parent_frame.istate.variant.as_ref().unwrap_or_else(|| {
2090 panic!(
2091 "Popping element for enum {} but no variant was selected",
2092 parent_shape
2093 )
2094 });
2095
2096 if variant.data.kind != facet_core::StructKind::Tuple {
2097 panic!(
2098 "Popping element for enum {}, but selected variant '{}' is not a tuple variant",
2099 parent_shape, variant.name
2100 );
2101 }
2102
2103 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2105 let field_index = previous_index - 1; if field_index >= variant.data.fields.len() {
2108 panic!(
2109 "Field index {} out of bounds for tuple enum variant '{}' of {} with {} fields",
2110 field_index,
2111 variant.name,
2112 parent_shape,
2113 variant.data.fields.len()
2114 );
2115 }
2116
2117 let field = &variant.data.fields[field_index];
2118 trace!(
2119 "[{}] Setting tuple enum variant field {} ({}) of variant '{}' in {}",
2120 frame_len,
2121 field_index.to_string().yellow(),
2122 field.name.bright_blue(),
2123 variant.name.yellow(),
2124 parent_shape.blue()
2125 );
2126
2127 unsafe {
2128 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2130 field_ptr
2131 .copy_from(
2132 PtrConst::new(frame.data.as_byte_ptr()),
2133 field.shape(),
2134 )
2135 .map_err(|_| ReflectError::Unsized {
2136 shape: field.shape(),
2137 })?; parent_frame.istate.fields.set(field_index);
2141
2142 self.mark_moved_out_of(&mut frame);
2144 }
2145 }
2146
2147 _ => {
2149 panic!(
2150 "FrameMode::ListElement pop expected parent to be List, Tuple Struct, or Tuple Enum Variant, but got {}",
2151 parent_shape
2152 );
2153 }
2154 }
2155 } else {
2156 trace!(
2158 "Popping uninitialized ListElement frame ({}), potential leak if allocated resources are not managed",
2159 frame.shape.yellow()
2160 );
2161 }
2162 }
2163
2164 FrameMode::MapValue {
2166 index: key_frame_index,
2167 } if frame.is_fully_initialized() => {
2168 let mut key_frame = self.frames.remove(key_frame_index);
2172
2173 if !key_frame.istate.fields.is_any_set() {
2175 panic!("key is not initialized when popping value frame");
2176 }
2177
2178 #[cfg(feature = "log")]
2180 let frame_len = self.frames.len();
2181 let parent_frame = self.frames.last_mut().unwrap();
2182 let parent_shape = parent_frame.shape;
2183
2184 match parent_shape.def {
2186 Def::Map(_) => {
2187 if let Def::Map(map_def) = parent_shape.def {
2189 trace!(
2190 "[{}] Inserting key-value pair into map {}",
2191 frame_len,
2192 parent_shape.blue()
2193 );
2194 unsafe {
2195 (map_def.vtable.insert_fn)(
2197 parent_frame.data.assume_init(),
2198 key_frame.data.assume_init(),
2199 PtrMut::new(frame.data.as_mut_byte_ptr()),
2200 );
2201 self.mark_moved_out_of(&mut key_frame);
2202 self.mark_moved_out_of(&mut frame);
2203 }
2204 } else {
2205 panic!("parent frame is not a map type");
2206 }
2207 }
2208 _ => {
2209 panic!("Expected map or hash map, got {}", frame.shape);
2210 }
2211 }
2212 }
2213
2214 FrameMode::OptionSome => {
2216 if frame.is_fully_initialized() {
2217 trace!("Popping OptionSome (fully init'd)");
2218
2219 #[cfg(feature = "log")]
2221 let frames_len = self.frames.len();
2222 let parent_frame = self.frames.last_mut().unwrap();
2223 let parent_shape = parent_frame.shape;
2224
2225 match parent_shape.def {
2227 Def::Option(option_def) => {
2228 trace!(
2229 "[{}] Setting Some value in option {}",
2230 frames_len,
2231 parent_shape.blue()
2232 );
2233 unsafe {
2234 (option_def.vtable.init_some_fn)(
2236 parent_frame.data,
2237 PtrConst::new(frame.data.as_byte_ptr()),
2238 );
2239 trace!("Marking parent frame as fully initialized");
2240 parent_frame.mark_fully_initialized();
2241
2242 self.mark_moved_out_of(&mut frame);
2243 }
2244 }
2245 _ => {
2246 panic!(
2247 "Expected parent frame to be an option type, got {}",
2248 frame.shape
2249 );
2250 }
2251 }
2252 } else {
2253 trace!("Popping OptionSome (not fully init'd)");
2254 }
2255 }
2256
2257 FrameMode::MapKey => {}
2260
2261 FrameMode::Field => {}
2263
2264 _ => {}
2266 }
2267
2268 Ok(Some(frame))
2269 }
2270
2271 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
2275 match frame.shape.def {
2276 Def::Struct(sd) => {
2277 for f in sd.fields {
2278 let id = ValueId {
2279 shape: f.shape(),
2280 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
2281 };
2282 if let Some(istate) = self.istates.remove(&id) {
2283 let frame = Frame::recompose(id, istate);
2284 self.evict_tree(frame);
2285 } else {
2286 trace!("No istate found for field {}", f.name);
2287 }
2288 }
2289 }
2290 Def::Enum(_ed) => {
2291 if let Some(variant) = &frame.istate.variant {
2293 trace!(
2294 "Evicting enum {} variant '{}' fields",
2295 frame.shape.blue(),
2296 variant.name.yellow()
2297 );
2298 for field in variant.data.fields {
2300 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2302 let field_shape = field.shape();
2303 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2304
2305 if let Some(field_istate) = self.istates.remove(&field_id) {
2307 trace!(
2308 "Evicting field '{}' (shape {}) of enum variant '{}'",
2309 field.name.bright_blue(),
2310 field_shape.green(),
2311 variant.name.yellow()
2312 );
2313 let field_frame = Frame::recompose(field_id, field_istate);
2315 self.evict_tree(field_frame);
2317 } else {
2318 trace!(
2319 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
2320 field.name.red(),
2321 field_shape.red(),
2322 variant.name.yellow()
2323 );
2324 }
2325 }
2326 } else {
2327 trace!(
2329 "Enum {} has no variant selected, no fields to evict.",
2330 frame.shape.blue()
2331 );
2332 }
2333 }
2334 _ => {}
2335 }
2336 frame
2337 }
2338
2339 #[allow(rustdoc::broken_intra_doc_links)]
2340 pub fn path(&self) -> String {
2343 let mut path = String::from("$");
2344
2345 for (i, frame) in self.frames.iter().enumerate() {
2346 if i == 0 {
2348 continue;
2349 }
2350
2351 match frame.istate.mode {
2352 FrameMode::ListElement => {
2353 if let Some(index) = frame.istate.list_index {
2355 path.push_str(&format!("[{}]", index));
2356 } else {
2357 path.push_str("[?]");
2358 }
2359 }
2360 FrameMode::MapKey => {
2361 path.push_str(".key");
2362 }
2363 FrameMode::MapValue { index: _ } => {
2364 path.push_str(".value");
2365 }
2366 FrameMode::OptionSome => {
2367 path.push_str(".some");
2368 }
2369 FrameMode::OptionNone => {
2370 path.push_str(".none");
2371 }
2372 FrameMode::Root => {
2373 }
2375 FrameMode::Field => {
2376 if let Some(index) = frame.field_index_in_parent {
2378 if let Some(parent) = self.frames.get(i - 1) {
2380 if let Def::Struct(sd) = parent.shape.def {
2381 if index < sd.fields.len() {
2382 let field_name = sd.fields[index].name;
2383 path.push('.');
2384 path.push_str(field_name);
2385 }
2386 } else if let Def::Enum(_) = parent.shape.def {
2387 if let Some(variant) = &parent.istate.variant {
2388 if index < variant.data.fields.len() {
2389 let field_name = variant.data.fields[index].name;
2390 path.push('.');
2391 path.push_str(field_name);
2392 }
2393 }
2394 }
2395 }
2396 }
2397 }
2398 }
2399 }
2400
2401 path
2402 }
2403
2404 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
2406 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
2407 shape: <()>::SHAPE,
2408 operation: "tried to check if field is set, but there was no frame",
2409 })?;
2410
2411 match frame.shape.def {
2412 Def::Struct(ref sd) => {
2413 if index >= sd.fields.len() {
2414 return Err(ReflectError::FieldError {
2415 shape: frame.shape,
2416 field_error: FieldError::NoSuchField,
2417 });
2418 }
2419 Ok(frame.istate.fields.has(index))
2420 }
2421 Def::Enum(_) => {
2422 let variant = frame.istate.variant.as_ref().ok_or(
2423 ReflectError::OperationFailed {
2424 shape: frame.shape,
2425 operation: "tried to check if field is set, but no variant was selected",
2426 },
2427 )?;
2428 if index >= variant.data.fields.len() {
2429 return Err(ReflectError::FieldError {
2430 shape: frame.shape,
2431 field_error: FieldError::NoSuchField,
2432 });
2433 }
2434 Ok(frame.istate.fields.has(index))
2435 }
2436 _ => Err(ReflectError::WasNotA {
2437 expected: "struct or enum",
2438 actual: frame.shape,
2439 }),
2440 }
2441 }
2442}
2443
2444impl Drop for Wip<'_> {
2445 fn drop(&mut self) {
2446 trace!("🧹🧹🧹 WIP is dropping");
2447
2448 while let Some(frame) = self.frames.pop() {
2449 self.track(frame);
2450 }
2451
2452 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
2453 trace!("No root found, we probably built already");
2454 return;
2455 };
2456
2457 let root_id = *root_id;
2458 let root_istate = self.istates.remove(&root_id).unwrap();
2459 let root = Frame::recompose(root_id, root_istate);
2460 let mut to_clean = vec![root];
2461
2462 let mut _root_guard: Option<Guard> = None;
2463
2464 while let Some(mut frame) = to_clean.pop() {
2465 trace!(
2466 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
2467 frame.shape.blue(),
2468 frame.data.as_byte_ptr(),
2469 frame.istate.flags.bright_magenta(),
2470 frame.istate.mode.yellow(),
2471 if frame.is_fully_initialized() {
2472 "✅"
2473 } else {
2474 "❌"
2475 }
2476 );
2477
2478 if frame.istate.flags.contains(FrameFlags::MOVED) {
2479 trace!(
2480 "{}",
2481 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
2482 );
2483 continue;
2484 }
2485
2486 match frame.shape.def {
2487 Def::Struct(sd) => {
2488 if frame.is_fully_initialized() {
2489 trace!(
2490 "Dropping fully initialized struct: {} at {:p}",
2491 frame.shape.green(),
2492 frame.data.as_byte_ptr()
2493 );
2494 let frame = self.evict_tree(frame);
2495 unsafe { frame.drop_and_dealloc_if_needed() };
2496 } else {
2497 let num_fields = sd.fields.len();
2498 trace!(
2499 "De-initializing struct {} at {:p} field-by-field ({} fields)",
2500 frame.shape.yellow(),
2501 frame.data.as_byte_ptr(),
2502 num_fields.to_string().bright_cyan()
2503 );
2504 for i in 0..num_fields {
2505 if frame.istate.fields.has(i) {
2506 let field = sd.fields[i];
2507 let field_shape = field.shape();
2508 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
2509 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2510 trace!(
2511 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
2512 i.to_string().bright_cyan(),
2513 field.name.bright_blue(),
2514 frame.shape.blue(),
2515 field_shape.green(),
2516 field_ptr.as_byte_ptr()
2517 );
2518 let istate = self.istates.remove(&field_id).unwrap();
2519 let field_frame = Frame::recompose(field_id, istate);
2520 to_clean.push(field_frame);
2521 } else {
2522 trace!(
2523 "Field #{} '{}' of {} was NOT initialized, skipping",
2524 i.to_string().bright_cyan(),
2525 sd.fields[i].name.bright_red(),
2526 frame.shape.red()
2527 );
2528 }
2529 }
2530
2531 if frame.istate.mode == FrameMode::Root {
2533 if let Ok(layout) = frame.shape.layout.sized_layout() {
2534 _root_guard = Some(Guard {
2535 ptr: frame.data.as_mut_byte_ptr(),
2536 layout,
2537 });
2538 }
2539 }
2540 }
2541 }
2542 Def::Enum(_ed) => {
2543 trace!(
2544 "{}",
2545 format_args!(
2546 "TODO: handle enum deallocation for {} at {:p}",
2547 frame.shape.yellow(),
2548 frame.data.as_byte_ptr()
2549 )
2550 .magenta()
2551 );
2552
2553 if frame.istate.mode == FrameMode::Root {
2555 if let Ok(layout) = frame.shape.layout.sized_layout() {
2556 _root_guard = Some(Guard {
2557 ptr: frame.data.as_mut_byte_ptr(),
2558 layout,
2559 });
2560 }
2561 }
2562 }
2563 Def::Array(_)
2564 | Def::Slice(_)
2565 | Def::List(_)
2566 | Def::Map(_)
2567 | Def::SmartPointer(_)
2568 | Def::Scalar(_)
2569 | Def::FunctionPointer(_)
2570 | Def::Option(_) => {
2571 trace!(
2572 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
2573 frame.shape.cyan(),
2574 frame.shape.def,
2575 frame.istate.mode.yellow(),
2576 frame.data.as_byte_ptr(),
2577 );
2578
2579 if frame.is_fully_initialized() {
2580 unsafe { frame.drop_and_dealloc_if_needed() }
2581 } else {
2582 frame.dealloc_if_needed();
2583 }
2584 }
2585 _ => {}
2586 }
2587 }
2588
2589 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
2591 for frame_id in all_ids.drain(..) {
2592 let frame_istate = self.istates.remove(&frame_id).unwrap();
2593
2594 trace!(
2595 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
2596 frame_id.shape.cyan(),
2597 frame_id.ptr,
2598 frame_istate.mode.yellow()
2599 );
2600 let mut frame = Frame::recompose(frame_id, frame_istate);
2601
2602 if frame.is_fully_initialized() {
2603 trace!("It's fully initialized, we can drop it");
2604 unsafe { frame.drop_and_dealloc_if_needed() };
2605 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
2606 trace!("Not initialized but allocated, let's free it");
2607 frame.dealloc_if_needed();
2608 }
2609 }
2610 }
2611}