1use crate::{ReflectError, ValueId};
2use crate::{debug, trace};
3use alloc::string::ToString;
4#[cfg(feature = "log")]
5use owo_colors::OwoColorize;
6
7use alloc::format;
8use alloc::{vec, vec::Vec};
9use bitflags::bitflags;
10use core::{fmt, marker::PhantomData};
11use facet_core::{
12 Def, DefaultInPlaceFn, Facet, FieldError, PtrConst, PtrMut, PtrUninit, ScalarAffinity, Shape,
13 TypeNameFn, TypeNameOpts, 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 DisplayToDebug<T>(T);
104
105impl<T> fmt::Debug for DisplayToDebug<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", &DisplayToDebug(&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 .field("id", &self.id())
122 .finish()
123 }
124}
125
126impl Frame {
127 fn id(&self) -> ValueId {
129 ValueId::new(self.shape, self.data.as_byte_ptr())
130 }
131
132 fn is_fully_initialized(&self) -> bool {
134 match self.shape.def {
135 Def::Struct(sd) => self.istate.fields.are_all_set(sd.fields.len()),
136 Def::Enum(_) => match self.istate.variant.as_ref() {
137 None => false,
138 Some(v) => self.istate.fields.are_all_set(v.data.fields.len()),
139 },
140 _ => self.istate.fields.are_all_set(1),
141 }
142 }
143
144 unsafe fn drop_and_dealloc_if_needed(mut self) {
146 trace!(
147 "[Frame::drop] Dropping frame for shape {} at {:p}",
148 self.shape.blue(),
149 self.data.as_byte_ptr()
150 );
151 if let Some(drop_in_place) = self.shape.vtable.drop_in_place {
152 unsafe {
153 trace!(
154 "[Frame::drop] Invoking drop_in_place for shape {} at {:p}",
155 self.shape.green(),
156 self.data.as_byte_ptr()
157 );
158 drop_in_place(self.data.assume_init());
159 }
160 } else {
161 trace!(
162 "[Frame::drop] No drop_in_place function for shape {}",
163 self.shape.blue(),
164 );
165 }
166 self.dealloc_if_needed();
167 }
168
169 unsafe fn mark_fully_initialized(&mut self) {
171 match self.shape.def {
172 Def::Struct(sd) => {
173 self.istate.fields = ISet::all(sd.fields);
174 }
175 Def::Enum(_) => {
176 if let Some(variant) = &self.istate.variant {
177 self.istate.fields = ISet::all(variant.data.fields);
178 }
179 }
180 _ => {
181 self.istate.fields.set(0);
182 }
183 }
184 }
185}
186
187struct IState {
189 variant: Option<Variant>,
191
192 fields: ISet,
194
195 depth: usize,
197
198 mode: FrameMode,
200
201 flags: FrameFlags,
203
204 list_index: Option<usize>,
206
207 #[allow(dead_code)]
209 map_key: Option<String>,
210}
211
212bitflags! {
213 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
215 pub struct FrameFlags: u64 {
216 const EMPTY = 0;
218
219 const ALLOCATED = 1 << 0;
221
222 const MOVED = 1 << 1;
226 }
227
228 }
230
231impl IState {
232 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
234 Self {
235 variant: None,
236 fields: Default::default(),
237 depth,
238 mode,
239 flags,
240 list_index: None,
241 map_key: None,
242 }
243 }
244
245 #[allow(dead_code)]
247 pub fn with_list_index(mut self, index: usize) -> Self {
248 self.list_index = Some(index);
249 self
250 }
251
252 #[allow(dead_code)]
254 pub fn with_map_key(mut self, key: String) -> Self {
255 self.map_key = Some(key);
256 self
257 }
258}
259
260#[derive(Debug, Clone, Copy, PartialEq, Eq)]
262pub enum FrameMode {
263 Root,
265 Field,
267 ListElement,
269 MapKey,
271 MapValue {
273 index: usize,
275 },
276 OptionSome,
278 OptionNone,
281}
282
283pub struct Wip<'facet_lifetime> {
285 frames: alloc::vec::Vec<Frame>,
287
288 istates: FlatMap<ValueId, IState>,
290
291 invariant: PhantomData<fn(&'facet_lifetime ()) -> &'facet_lifetime ()>,
292}
293
294impl<'facet_lifetime> Wip<'facet_lifetime> {
295 pub fn put_peek(
297 self,
298 peek: crate::Peek<'_, 'facet_lifetime>,
299 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
300 self.put_shape(peek.data, peek.shape)
301 }
302
303 pub fn frames_count(&self) -> usize {
305 self.frames.len()
306 }
307
308 pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
310 let data = shape
311 .allocate()
312 .map_err(|_| ReflectError::Unsized { shape })?;
313 Ok(Self {
314 frames: alloc::vec![Frame {
315 data,
316 shape,
317 field_index_in_parent: None,
318 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
319 }],
320 istates: Default::default(),
321 invariant: PhantomData,
322 })
323 }
324
325 pub fn alloc<S: Facet<'facet_lifetime>>() -> Result<Self, ReflectError> {
327 Self::alloc_shape(S::SHAPE)
328 }
329
330 fn track(&mut self, frame: Frame) {
331 if frame.istate.flags.contains(FrameFlags::MOVED) {
337 return;
339 }
340
341 self.istates.insert(frame.id(), frame.istate);
342 }
343
344 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame) {
345 unsafe fn mark_subtree_moved(wip: &mut Wip, id: ValueId) {
348 unsafe {
350 if let Some(mut istate) = wip.istates.remove(&id) {
352 istate.flags.insert(FrameFlags::MOVED);
354
355 match id.shape.def {
357 Def::Struct(sd) => {
358 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
359 for field in sd.fields.iter() {
360 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
361 let field_id =
362 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
363 mark_subtree_moved(wip, field_id);
365 }
366 }
367 Def::Enum(_) => {
368 if let Some(variant) = &istate.variant {
370 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
371 for field in variant.data.fields.iter() {
372 let field_ptr_uninit =
373 container_ptr.field_uninit_at(field.offset);
374 let field_id =
375 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
376 mark_subtree_moved(wip, field_id);
378 }
379 }
380 }
381 _ => {}
385 }
386
387 if istate.flags.contains(FrameFlags::ALLOCATED) {
390 let mut temp_frame = Frame::recompose(id, istate);
392 temp_frame.dealloc_if_needed();
393 }
394 }
395 }
397 }
398
399 unsafe {
402 let frame_id = frame.id();
404
405 let variant_opt = frame.istate.variant;
407
408 frame.istate.flags.insert(FrameFlags::MOVED);
410 ISet::clear(&mut frame.istate.fields);
411
412 match frame.shape.def {
415 Def::Struct(sd) => {
416 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
417 for field in sd.fields.iter() {
418 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
419 let field_id = ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
420 mark_subtree_moved(self, field_id);
421 }
422 }
423 Def::Enum(_) => {
424 if let Some(variant) = &variant_opt {
426 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
427 for field in variant.data.fields.iter() {
428 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
429 let field_id =
430 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
431 mark_subtree_moved(self, field_id);
432 }
433 }
434 }
435 _ => {}
437 }
438
439 frame.istate.variant = None;
441
442 self.istates.remove(&frame_id);
444
445 if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
447 frame.dealloc_if_needed();
448 }
449 }
450 }
451
452 pub fn shape(&self) -> &'static Shape {
454 self.frames.last().expect("must have frames left").shape
455 }
456
457 pub fn innermost_shape(&self) -> &'static Shape {
461 let mut current_shape = self.shape();
462
463 while let Some(inner_fn) = current_shape.inner {
465 current_shape = inner_fn();
466 }
467
468 current_shape
469 }
470
471 pub fn in_option(&self) -> bool {
473 let Some(frame) = self.frames.last() else {
474 return false;
475 };
476 matches!(frame.istate.mode, FrameMode::OptionSome)
477 }
478
479 pub fn mode(&self) -> FrameMode {
481 self.frames.last().unwrap().istate.mode
482 }
483
484 pub fn build(mut self) -> Result<HeapValue<'facet_lifetime>, ReflectError> {
486 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
487
488 if self.frames.is_empty() {
490 panic!("No frames in WIP during build: stack is empty (you popped too much)");
491 }
492 if self.frames.len() != 1 {
493 panic!(
494 "You must pop frames so that only the root frame remains before calling build (frames left: {})",
495 self.frames.len()
496 );
497 }
498
499 let root_frame = &self.frames[0];
501
502 enum FrameRef {
503 Root,
504 ById(ValueId),
505 }
506 let mut to_check = alloc::vec![FrameRef::Root];
507
508 while let Some(fr) = to_check.pop() {
510 let (id, istate) = match fr {
511 FrameRef::Root => (root_frame.id(), &root_frame.istate),
512 FrameRef::ById(id) => {
513 let istate = self.istates.get(&id).unwrap();
515 (id, istate)
516 }
517 };
518
519 trace!(
520 "Checking shape {} at {:p}, flags={:?}, mode={:?}",
521 id.shape.blue(),
522 id.ptr,
523 istate.flags.bright_magenta(),
524 istate.mode,
525 );
526
527 if istate.flags.contains(FrameFlags::MOVED) {
529 trace!(
530 "{}",
531 "Frame was moved out of, skipping initialization check".yellow()
532 );
533 continue;
534 }
535
536 match id.shape.def {
538 Def::Struct(sd) => {
539 for i in 0..sd.fields.len() {
541 if !istate.fields.has(i) {
542 let field = &sd.fields[i];
543 return Err(ReflectError::UninitializedField {
544 shape: id.shape,
545 field_name: field.name,
546 });
547 }
548 }
549
550 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
551
552 #[allow(clippy::unused_enumerate_index)]
554 for (_i, field) in sd.fields.iter().enumerate() {
555 let field_shape = field.shape();
556 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
557 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
558
559 if self.istates.contains_key(&field_id) {
560 debug!(
561 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
562 _i.to_string().bright_cyan(),
563 field.name.bright_blue(),
564 id.shape.blue(),
565 field_shape.green(),
566 field_ptr.as_byte_ptr()
567 );
568 to_check.push(FrameRef::ById(field_id));
569 }
570 }
571 }
572 Def::Enum(_ed) => {
573 if let Some(variant) = &istate.variant {
574 for (i, field) in variant.data.fields.iter().enumerate() {
576 if !istate.fields.has(i) {
577 return Err(ReflectError::UninitializedEnumField {
578 shape: id.shape,
579 variant_name: variant.name,
580 field_name: field.name,
581 });
582 }
583 }
584
585 #[allow(clippy::unused_enumerate_index)]
587 for (_i, field) in variant.data.fields.iter().enumerate() {
588 let field_shape = field.shape();
589 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
590 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
592 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
593
594 if self.istates.contains_key(&field_id) {
595 debug!(
596 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
597 _i.to_string().bright_cyan(),
598 field.name.bright_blue(),
599 variant.name.yellow(),
600 id.shape.blue(),
601 field_shape.green(),
602 field_ptr.as_byte_ptr()
603 );
604 to_check.push(FrameRef::ById(field_id));
605 }
606 }
607 } else {
608 debug!("Found no variant selected for enum");
610 return Err(ReflectError::NoVariantSelected { shape: id.shape });
611 }
612 }
613 Def::List(_)
617 | Def::Map(_)
618 | Def::Option(_)
619 | Def::Scalar(_)
620 | Def::FunctionPointer(_)
621 | Def::SmartPointer(_)
622 | Def::Array(_)
623 | Def::Slice(_) => {
624 if !istate.fields.are_all_set(1) {
625 match istate.mode {
627 FrameMode::OptionNone => {
628 debug!("Found uninitialized value (option none)");
630 return Err(ReflectError::UninitializedValue { shape: id.shape });
631 }
632 _ => {
634 debug!("Found uninitialized value (list/map/option/etc.)");
635 return Err(ReflectError::UninitializedValue { shape: id.shape });
636 }
637 }
638 }
639 }
647 _ => {
649 if !istate.fields.are_all_set(1) {
651 debug!("Found uninitialized value (other)");
652 return Err(ReflectError::UninitializedValue { shape: id.shape });
653 }
654 }
655 }
656 }
657
658 debug!("All reachable frames checked and initialized.");
660
661 let root_shape = root_frame.shape;
664 let root_data = unsafe { root_frame.data.assume_init() };
665 if let Some(invariant_fn) = root_shape.vtable.invariants {
666 debug!(
667 "Checking invariants for root shape {} at {:p}",
668 root_shape.green(),
669 root_data.as_byte_ptr()
670 );
671 if !unsafe { invariant_fn(PtrConst::new(root_data.as_byte_ptr())) } {
672 return Err(ReflectError::InvariantViolation {
673 invariant: "Custom validation function returned false",
674 });
675 }
676 } else {
677 debug!(
678 "No invariants to check for root shape {}",
679 root_shape.blue()
680 );
681 }
682
683 {
685 FlatMap::clear(&mut self.istates);
686 self.frames.clear();
687 }
688
689 let guard = Guard {
691 ptr: root_data.as_mut_byte_ptr(),
692 layout: match root_shape.layout {
693 facet_core::ShapeLayout::Sized(layout) => layout,
694 facet_core::ShapeLayout::Unsized => panic!("Unsized layout not supported"),
695 },
696 };
697
698 Ok(HeapValue {
699 guard: Some(guard),
700 shape: root_shape,
701 phantom: PhantomData,
702 })
703 }
704
705 pub fn field(mut self, index: usize) -> Result<Self, ReflectError> {
717 let frame = self.frames.last_mut().unwrap();
718 let shape = frame.shape;
719
720 let (field, field_offset) = match shape.def {
721 Def::Struct(def) => {
722 if index >= def.fields.len() {
723 return Err(ReflectError::FieldError {
724 shape,
725 field_error: FieldError::IndexOutOfBounds {
726 index,
727 bound: def.fields.len(),
728 },
729 });
730 }
731 let field = &def.fields[index];
732 (field, field.offset)
733 }
734 Def::Enum(_) => {
735 let Some(variant) = frame.istate.variant.as_ref() else {
736 return Err(ReflectError::OperationFailed {
737 shape,
738 operation: "tried to access a field but no variant was selected",
739 });
740 };
741
742 if index >= variant.data.fields.len() {
743 return Err(ReflectError::FieldError {
744 shape,
745 field_error: FieldError::IndexOutOfBounds {
746 index,
747 bound: variant.data.fields.len(),
748 },
749 });
750 }
751
752 let field = &variant.data.fields[index];
753 (field, field.offset)
754 }
755 _ => {
756 return Err(ReflectError::WasNotA {
757 expected: "struct or enum",
758 actual: shape,
759 });
760 }
761 };
762
763 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
764
765 let mut frame = Frame {
766 data: field_data,
767 shape: field.shape(),
768 field_index_in_parent: Some(index),
769 istate: IState::new(self.frames.len(), FrameMode::Field, FrameFlags::EMPTY),
771 };
772 debug!(
773 "[{}] Selecting field {} ({}#{}) of {}",
774 self.frames.len(),
775 field.name.blue(),
776 field.shape().green(),
777 index.yellow(),
778 shape.blue(),
779 );
780 if let Some(iset) = self.istates.remove(&frame.id()) {
781 trace!(
782 "[{}] Restoring saved state for {} (istate.mode = {:?}, istate.fields = {:?}, istate.flags = {:?}, istate.depth = {:?})",
783 self.frames.len(),
784 frame.id().shape.blue(),
785 iset.mode,
786 iset.fields,
787 iset.flags,
788 iset.depth
789 );
790 frame.istate = iset;
791 } else {
792 trace!(
793 "[{}] no saved state for field {} ({}#{}) of {}",
794 self.frames.len(),
795 field.name.blue(),
796 field.shape().green(),
797 index.yellow(),
798 shape.blue(),
799 );
800 }
801 self.frames.push(frame);
802 Ok(self)
803 }
804
805 pub fn field_index(&self, name: &str) -> Option<usize> {
817 fn find_field_index(fields: &'static [facet_core::Field], name: &str) -> Option<usize> {
818 fields.iter().position(|f| f.name == name)
819 }
820
821 let frame = self.frames.last()?;
822 match frame.shape.def {
823 Def::Struct(def) => find_field_index(def.fields, name),
824 Def::Enum(_) => {
825 let variant = frame.istate.variant.as_ref()?;
826 find_field_index(variant.data.fields, name)
827 }
828 _ => None,
829 }
830 }
831
832 pub fn field_named(self, name: &str) -> Result<Self, ReflectError> {
844 let frame = self.frames.last().unwrap();
845 let shape = frame.shape;
846
847 if let Def::Enum(_) = shape.def {
849 if frame.istate.variant.is_none() {
850 return Err(ReflectError::OperationFailed {
851 shape,
852 operation: "tried to access a field by name but no variant was selected",
853 });
854 }
855 }
856
857 let index = self.field_index(name).ok_or(ReflectError::FieldError {
858 shape,
859 field_error: FieldError::NoSuchField,
860 })?;
861
862 self.field(index)
863 }
864
865 pub fn put<T: Facet<'facet_lifetime>>(
876 self,
877 t: T,
878 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
879 let shape = T::SHAPE;
880 let ptr_const = PtrConst::new(&t as *const T as *const u8);
881 let res = self.put_shape(ptr_const, shape);
882 core::mem::forget(t); res
884 }
885
886 pub fn try_put<T: Facet<'facet_lifetime>>(
897 self,
898 t: T,
899 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
900 let shape = T::SHAPE;
901 let ptr_const = PtrConst::new(&t as *const T as *const u8);
902 let res = self.put_shape(ptr_const, shape);
903 core::mem::forget(t); res
905 }
906
907 pub fn put_shape(
909 mut self,
910 src: PtrConst<'_>,
911 src_shape: &'static Shape,
912 ) -> Result<Wip<'facet_lifetime>, ReflectError> {
913 let Some(frame) = self.frames.last_mut() else {
914 return Err(ReflectError::OperationFailed {
915 shape: src_shape,
916 operation: "tried to put a value but there was no frame to put into",
917 });
918 };
919
920 if frame.shape != src_shape {
922 trace!(
923 "Trying to put a {} into a {}",
924 src_shape.yellow(),
925 frame.shape.magenta()
926 );
927
928 if let Some(inner_fn) = frame.shape.inner {
930 let inner_shape = inner_fn();
932
933 if src_shape == inner_shape {
935 if let Some(try_from_fn) = frame.shape.vtable.try_from {
937 match unsafe { (try_from_fn)(src, src_shape, frame.data) } {
938 Ok(_) => {
939 unsafe {
940 frame.mark_fully_initialized();
941 }
942
943 let shape = frame.shape;
944 let index = frame.field_index_in_parent;
945
946 self.mark_field_as_initialized(shape, index)?;
948
949 debug!(
950 "[{}] Just put a {} value into transparent type {}",
951 self.frames.len(),
952 src_shape.green(),
953 shape.blue()
954 );
955
956 return Ok(self);
957 }
958 Err(e) => {
959 return Err(ReflectError::TryFromError {
960 inner: e,
961 src_shape,
962 dst_shape: frame.shape,
963 });
964 }
965 }
966 } else {
967 debug!(
969 "No try_from_inner function for transparent type, falling back to TryFrom"
970 );
971 }
972 }
973 }
974
975 if let Some(try_from) = frame.shape.vtable.try_from {
977 match unsafe { try_from(src, src_shape, frame.data) } {
978 Ok(_) => {
979 unsafe {
980 frame.mark_fully_initialized();
981 }
982
983 let shape = frame.shape;
984 let index = frame.field_index_in_parent;
985
986 self.mark_field_as_initialized(shape, index)?;
988
989 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
990
991 return Ok(self);
992 }
993 Err(e) => {
994 return Err(ReflectError::TryFromError {
995 inner: e,
996 src_shape,
997 dst_shape: frame.shape,
998 });
999 }
1000 }
1001 }
1002
1003 if let Def::Option(od) = frame.shape.def {
1006 if od.t() == src_shape {
1008 debug!("Putting into an Option<T>!");
1009 if frame.istate.fields.is_any_set() {
1010 let data = unsafe { frame.data.assume_init() };
1011 unsafe { (od.vtable.replace_with_fn)(data, Some(src)) };
1012 } else {
1013 let data = frame.data;
1014 unsafe { (od.vtable.init_some_fn)(data, src) };
1015 }
1016 unsafe {
1017 frame.mark_fully_initialized();
1018 }
1019
1020 let shape = frame.shape;
1021 let index = frame.field_index_in_parent;
1022
1023 self.mark_field_as_initialized(shape, index)?;
1025
1026 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1027
1028 return Ok(self);
1029 }
1030 }
1031
1032 if let Def::Struct(sd) = frame.shape.def {
1036 for (i, field) in sd.fields.iter().enumerate() {
1038 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1039 debug!(
1040 "Found uninitialized field {} with matching type {}",
1041 i.to_string().blue(),
1042 src_shape.green()
1043 );
1044
1045 unsafe {
1047 let field_data = frame.data.field_uninit_at(field.offset);
1048 field_data.copy_from(src, field.shape()).map_err(|_| {
1049 ReflectError::Unsized {
1050 shape: field.shape(),
1051 }
1052 })?;
1053 frame.istate.fields.set(i);
1054 }
1055
1056 let shape = frame.shape;
1057 let index = frame.field_index_in_parent;
1058
1059 if frame.is_fully_initialized() {
1061 self.mark_field_as_initialized(shape, index)?;
1062 }
1063
1064 debug!(
1065 "[{}] Put a {} value into field {} of {}",
1066 self.frames.len(),
1067 src_shape.green(),
1068 i.to_string().blue(),
1069 shape.green()
1070 );
1071
1072 return Ok(self);
1073 }
1074 }
1075 }
1076
1077 if let Def::Enum(_) = frame.shape.def {
1080 if let Some(variant) = &frame.istate.variant {
1082 for (i, field) in variant.data.fields.iter().enumerate() {
1084 if !frame.istate.fields.has(i) && field.shape() == src_shape {
1085 debug!(
1086 "Found uninitialized field {} in enum variant '{}' with matching type {}",
1087 i.to_string().blue(),
1088 variant.name.bright_yellow(),
1089 src_shape.green()
1090 );
1091
1092 unsafe {
1094 let field_data = frame.data.field_uninit_at(field.offset);
1095 field_data.copy_from(src, field.shape()).map_err(|_| {
1096 ReflectError::Unsized {
1097 shape: field.shape(),
1098 }
1099 })?;
1100 frame.istate.fields.set(i);
1101 }
1102
1103 let shape = frame.shape;
1104 let index = frame.field_index_in_parent;
1105
1106 #[allow(unused)]
1107 let variant_name = variant.name;
1108
1109 if frame.is_fully_initialized() {
1111 self.mark_field_as_initialized(shape, index)?;
1112 }
1113
1114 debug!(
1115 "[{}] Put a {} value into field {} of variant '{}' in enum {}",
1116 self.frames.len(),
1117 src_shape.green(),
1118 i.to_string().blue(),
1119 variant_name.bright_yellow(),
1120 shape.green()
1121 );
1122
1123 return Ok(self);
1124 }
1125 }
1126 }
1127 }
1128
1129 return Err(ReflectError::WrongShape {
1130 expected: frame.shape,
1131 actual: src_shape,
1132 });
1133 }
1134
1135 if frame.istate.variant.is_some() || frame.istate.fields.is_any_set() {
1137 debug!("De-initializing partially initialized {:?}", frame.yellow());
1138
1139 match frame.shape.def {
1140 Def::Struct(sd) => {
1141 for (i, field) in sd.fields.iter().enumerate() {
1142 if frame.istate.fields.has(i) {
1143 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1144 unsafe {
1145 let field_ptr = frame.data.as_mut_byte_ptr().add(field.offset);
1146 drop_fn(PtrMut::new(field_ptr));
1147 }
1148 }
1149 }
1150 }
1151 }
1152 Def::Enum(_) => {
1153 if let Some(variant) = &frame.istate.variant {
1154 for (i, field) in variant.data.fields.iter().enumerate() {
1155 if frame.istate.fields.has(i) {
1156 if let Some(drop_fn) = field.shape().vtable.drop_in_place {
1157 unsafe {
1158 let field_ptr =
1159 frame.data.as_mut_byte_ptr().add(field.offset);
1160 drop_fn(PtrMut::new(field_ptr));
1161 }
1162 }
1163 }
1164 }
1165 }
1166 }
1167 _ => {
1168 if frame.istate.fields.is_any_set() {
1170 debug!("Scalar type was set...");
1171 if let Some(drop_fn) = frame.shape.vtable.drop_in_place {
1172 debug!("And it has a drop fn, dropping now!");
1173 unsafe {
1174 drop_fn(frame.data.assume_init());
1175 }
1176 }
1177 }
1178 }
1179 }
1180
1181 frame.istate.variant = None;
1183 ISet::clear(&mut frame.istate.fields);
1184 }
1185
1186 unsafe {
1187 frame
1189 .data
1190 .copy_from(src, frame.shape)
1191 .map_err(|_| ReflectError::Unsized { shape: frame.shape })?;
1192 frame.mark_fully_initialized();
1193 }
1194
1195 let shape = frame.shape;
1196 let index = frame.field_index_in_parent;
1197
1198 self.mark_field_as_initialized(shape, index)?;
1200
1201 debug!("[{}] Just put a {} value", self.frames.len(), shape.green());
1202
1203 Ok(self)
1204 }
1205
1206 pub fn parse(mut self, s: &str) -> Result<Self, ReflectError> {
1208 let Some(frame) = self.frames.last_mut() else {
1209 return Err(ReflectError::OperationFailed {
1210 shape: <()>::SHAPE,
1211 operation: "tried to parse value but there was no frame",
1212 });
1213 };
1214
1215 let shape = frame.shape;
1216 let index = frame.field_index_in_parent;
1217
1218 let Some(parse_fn) = frame.shape.vtable.parse else {
1219 return Err(ReflectError::OperationFailed {
1220 shape: frame.shape,
1221 operation: "type does not implement Parse",
1222 });
1223 };
1224 match unsafe { (parse_fn)(s, frame.data) } {
1225 Ok(_res) => {
1226 unsafe {
1227 frame.mark_fully_initialized();
1228 }
1229
1230 self.mark_field_as_initialized(shape, index)?;
1232
1233 Ok(self)
1234 }
1235 Err(_) => Err(ReflectError::OperationFailed {
1236 shape,
1237 operation: "parsing",
1238 }),
1239 }
1240 }
1241
1242 pub fn put_from_fn(mut self, default_in_place: DefaultInPlaceFn) -> Result<Self, ReflectError> {
1244 let Some(frame) = self.frames.last_mut() else {
1245 return Err(ReflectError::OperationFailed {
1246 shape: <()>::SHAPE,
1247 operation: "tried to put value from fn but there was no frame",
1248 });
1249 };
1250
1251 unsafe {
1252 default_in_place(frame.data);
1253 frame.mark_fully_initialized();
1254 }
1255
1256 let shape = frame.shape;
1257 let index = frame.field_index_in_parent;
1258
1259 self.mark_field_as_initialized(shape, index)?;
1261
1262 Ok(self)
1263 }
1264
1265 pub fn put_default(self) -> Result<Self, ReflectError> {
1267 let Some(frame) = self.frames.last() else {
1268 return Err(ReflectError::OperationFailed {
1269 shape: <()>::SHAPE,
1270 operation: "tried to put default value but there was no frame",
1271 });
1272 };
1273
1274 let vtable = frame.shape.vtable;
1275 let Some(default_in_place) = vtable.default_in_place else {
1276 return Err(ReflectError::OperationFailed {
1277 shape: frame.shape,
1278 operation: "type does not implement Default",
1279 });
1280 };
1281
1282 self.put_from_fn(default_in_place)
1283 }
1284
1285 fn mark_field_as_initialized(
1287 &mut self,
1288 shape: &'static Shape,
1289 index: Option<usize>,
1290 ) -> Result<(), ReflectError> {
1291 if let Some(index) = index {
1292 let parent_index = self.frames.len().saturating_sub(2);
1293 #[cfg(feature = "log")]
1294 let num_frames = self.frames.len();
1295 let Some(parent) = self.frames.get_mut(parent_index) else {
1296 return Err(ReflectError::OperationFailed {
1297 shape,
1298 operation: "was supposed to mark a field as initialized, but there was no parent frame",
1299 });
1300 };
1301 #[cfg(feature = "log")]
1302 let parent_shape = parent.shape;
1303 trace!(
1304 "[{}] {}.{} initialized with {}",
1305 num_frames,
1306 parent_shape.blue(),
1307 index.yellow(),
1308 shape.green()
1309 );
1310
1311 if matches!(parent.shape.def, Def::Enum(_)) && parent.istate.variant.is_none() {
1312 return Err(ReflectError::OperationFailed {
1313 shape,
1314 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
1315 });
1316 }
1317
1318 if parent.istate.fields.has(index) {
1319 return Err(ReflectError::OperationFailed {
1320 shape,
1321 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
1322 });
1323 }
1324
1325 parent.istate.fields.set(index);
1326 }
1327 Ok(())
1328 }
1329
1330 pub fn element_shape(&self) -> Result<&'static Shape, ReflectError> {
1332 let frame = self.frames.last().unwrap();
1333 let shape = frame.shape;
1334
1335 match shape.def {
1336 Def::List(list_def) => Ok(list_def.t()),
1337 _ => Err(ReflectError::WasNotA {
1338 expected: "list or array",
1339 actual: shape,
1340 }),
1341 }
1342 }
1343
1344 pub fn key_shape(&self) -> Result<&'static Shape, ReflectError> {
1346 let frame = self.frames.last().unwrap();
1347 let shape = frame.shape;
1348
1349 match shape.def {
1350 Def::Map(map_def) => Ok(map_def.k),
1351 _ => Err(ReflectError::WasNotA {
1352 expected: "map",
1353 actual: shape,
1354 }),
1355 }
1356 }
1357
1358 pub fn put_empty_list(mut self) -> Result<Self, ReflectError> {
1360 let Some(frame) = self.frames.last_mut() else {
1361 return Err(ReflectError::OperationFailed {
1362 shape: <()>::SHAPE,
1363 operation: "tried to create empty list but there was no frame",
1364 });
1365 };
1366
1367 if !matches!(frame.shape.def, Def::List(_)) {
1368 return Err(ReflectError::WasNotA {
1369 expected: "list or array",
1370 actual: frame.shape,
1371 });
1372 }
1373
1374 let vtable = frame.shape.vtable;
1375
1376 let Some(default_in_place) = vtable.default_in_place else {
1378 return Err(ReflectError::OperationFailed {
1379 shape: frame.shape,
1380 operation: "list type does not implement Default",
1381 });
1382 };
1383
1384 unsafe {
1385 default_in_place(frame.data);
1386 frame.mark_fully_initialized();
1387 }
1388
1389 let shape = frame.shape;
1390 let index = frame.field_index_in_parent;
1391
1392 self.mark_field_as_initialized(shape, index)?;
1394
1395 Ok(self)
1396 }
1397
1398 pub fn put_empty_map(mut self) -> Result<Self, ReflectError> {
1400 let Some(frame) = self.frames.last_mut() else {
1401 return Err(ReflectError::OperationFailed {
1402 shape: <()>::SHAPE,
1403 operation: "tried to create empty map but there was no frame",
1404 });
1405 };
1406
1407 if !matches!(frame.shape.def, Def::Map(_)) {
1408 return Err(ReflectError::WasNotA {
1409 expected: "map or hash map",
1410 actual: frame.shape,
1411 });
1412 }
1413
1414 let vtable = frame.shape.vtable;
1415
1416 let Some(default_in_place) = vtable.default_in_place else {
1418 return Err(ReflectError::OperationFailed {
1419 shape: frame.shape,
1420 operation: "map type does not implement Default",
1421 });
1422 };
1423
1424 unsafe {
1425 default_in_place(frame.data);
1426 frame.mark_fully_initialized();
1427 }
1428
1429 let shape = frame.shape;
1430 let index = frame.field_index_in_parent;
1431
1432 self.mark_field_as_initialized(shape, index)?;
1434
1435 Ok(self)
1436 }
1437
1438 pub fn begin_pushback(mut self) -> Result<Self, ReflectError> {
1443 let Some(frame) = self.frames.last_mut() else {
1444 return Err(ReflectError::OperationFailed {
1445 shape: <()>::SHAPE,
1446 operation: "tried to begin pushback but there was no frame",
1447 });
1448 };
1449
1450 let is_list = matches!(frame.shape.def, Def::List(_));
1451 let is_tuple_struct_or_variant = match frame.shape.def {
1452 Def::Scalar(sd) => matches!(sd.affinity, ScalarAffinity::Empty(_)),
1453 Def::Struct(sd) => sd.kind == facet_core::StructKind::Tuple,
1454 Def::Enum(_) => {
1455 if let Some(variant) = &frame.istate.variant {
1457 variant.data.kind == facet_core::StructKind::Tuple
1458 } else {
1459 false }
1468 }
1469 _ => false,
1470 };
1471
1472 if !is_list && !is_tuple_struct_or_variant {
1473 return Err(ReflectError::WasNotA {
1474 expected: "list, array, or tuple-like struct/enum variant",
1475 actual: frame.shape,
1476 });
1477 }
1478
1479 if is_list {
1481 let vtable = frame.shape.vtable;
1482 if !frame.istate.fields.has(0) {
1484 let Some(default_in_place) = vtable.default_in_place else {
1485 return Err(ReflectError::OperationFailed {
1486 shape: frame.shape,
1487 operation: "list type does not implement Default, cannot begin pushback",
1488 });
1489 };
1490
1491 unsafe {
1492 default_in_place(frame.data);
1493 frame.istate.fields.set(0);
1495 }
1496 }
1497 }
1498 Ok(self)
1501 }
1502
1503 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError> {
1505 let Some(frame) = self.frames.last_mut() else {
1506 return Err(ReflectError::OperationFailed {
1507 shape: <()>::SHAPE,
1508 operation: "tried to begin map insertion but there was no frame",
1509 });
1510 };
1511
1512 if !matches!(frame.shape.def, Def::Map(_)) {
1513 return Err(ReflectError::WasNotA {
1514 expected: "map or hash map",
1515 actual: frame.shape,
1516 });
1517 }
1518
1519 let vtable = frame.shape.vtable;
1520
1521 if !frame.istate.fields.has(0) {
1523 let Some(default_in_place) = vtable.default_in_place else {
1524 return Err(ReflectError::OperationFailed {
1525 shape: frame.shape,
1526 operation: "map type does not implement Default",
1527 });
1528 };
1529
1530 unsafe {
1531 default_in_place(frame.data);
1532 frame.istate.fields.set(0);
1533 }
1534 }
1535
1536 Ok(self)
1537 }
1538
1539 pub fn push(mut self) -> Result<Self, ReflectError> {
1544 let frame_len = self.frames.len();
1546 let frame = self
1547 .frames
1548 .last_mut()
1549 .ok_or(ReflectError::OperationFailed {
1550 shape: <()>::SHAPE,
1551 operation: "tried to push but there was no frame",
1552 })?;
1553 let seq_shape = frame.shape;
1554
1555 let (element_shape, context_str): (&'static Shape, _) = match seq_shape.def {
1557 Def::List(_) => {
1558 if !frame.istate.fields.has(0) {
1560 return self.begin_pushback()?.push();
1563 }
1564 let shape = self.element_shape()?;
1567 (shape, "list")
1568 }
1569
1570 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
1571 let field_index = {
1573 let next_idx = frame.istate.list_index.unwrap_or(0);
1575 frame.istate.list_index = Some(next_idx + 1);
1576 next_idx
1577 };
1578 if field_index >= sd.fields.len() {
1580 return Err(ReflectError::FieldError {
1581 shape: seq_shape,
1582 field_error: FieldError::IndexOutOfBounds {
1583 index: field_index,
1584 bound: sd.fields.len(),
1585 },
1586 });
1587 }
1588 (sd.fields[field_index].shape(), "tuple struct")
1590 }
1591
1592 Def::Enum(_) => {
1593 let variant =
1595 frame
1596 .istate
1597 .variant
1598 .as_ref()
1599 .ok_or(ReflectError::OperationFailed {
1600 shape: seq_shape,
1601 operation: "tried to push onto enum but no variant was selected",
1602 })?;
1603 if variant.data.kind != facet_core::StructKind::Tuple {
1605 return Err(ReflectError::WasNotA {
1606 expected: "tuple-like enum variant",
1607 actual: seq_shape, });
1609 }
1610 let field_index = {
1612 let next_idx = frame.istate.list_index.unwrap_or(0);
1614 frame.istate.list_index = Some(next_idx + 1);
1615 next_idx
1616 };
1617 if field_index >= variant.data.fields.len() {
1619 return Err(ReflectError::FieldError {
1620 shape: seq_shape, field_error: FieldError::IndexOutOfBounds {
1622 index: field_index,
1623 bound: variant.data.fields.len(),
1624 },
1625 });
1626 }
1627 (
1629 variant.data.fields[field_index].shape(),
1630 "tuple enum variant",
1631 )
1632 }
1633
1634 Def::Scalar(sd) if matches!(sd.affinity, ScalarAffinity::Empty(_)) => {
1635 return Err(ReflectError::OperationFailed {
1637 shape: seq_shape,
1638 operation: "cannot push elements to unit type ()",
1639 });
1640 }
1641
1642 _ => {
1643 return Err(ReflectError::WasNotA {
1645 expected: "list, array, tuple struct, or tuple enum variant",
1646 actual: seq_shape,
1647 });
1648 }
1649 };
1650
1651 let element_data = element_shape
1653 .allocate()
1654 .map_err(|_| ReflectError::Unsized {
1655 shape: element_shape,
1656 })?;
1657
1658 let element_frame = Frame {
1660 data: element_data,
1661 shape: element_shape,
1662 field_index_in_parent: None, istate: IState::new(
1664 frame_len, FrameMode::ListElement, FrameFlags::ALLOCATED,
1667 ),
1668 };
1669
1670 trace!(
1671 "[{}] Pushing element of type {} to {} {}",
1672 frame_len,
1673 element_shape.green(),
1674 context_str, seq_shape.blue(),
1676 );
1677 let _ = context_str;
1678
1679 self.frames.push(element_frame);
1680 Ok(self)
1681 }
1682
1683 pub fn push_some(mut self) -> Result<Self, ReflectError> {
1685 let frame = self.frames.last().unwrap();
1687 let option_shape = frame.shape;
1688
1689 let Def::Option(option_def) = option_shape.def else {
1691 return Err(ReflectError::WasNotA {
1692 expected: "option",
1693 actual: option_shape,
1694 });
1695 };
1696
1697 let inner_shape = option_def.t();
1699
1700 let inner_data = inner_shape
1702 .allocate()
1703 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1704
1705 let inner_frame = Frame {
1707 data: inner_data,
1708 shape: inner_shape,
1709 field_index_in_parent: None,
1711 istate: IState::new(
1712 self.frames.len(),
1713 FrameMode::OptionSome,
1714 FrameFlags::ALLOCATED,
1716 ),
1717 };
1718
1719 trace!(
1720 "[{}] Pushing option frame for {}",
1721 self.frames.len(),
1722 option_shape.blue(),
1723 );
1724
1725 self.frames.push(inner_frame);
1726 Ok(self)
1727 }
1728
1729 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError> {
1739 let Some(frame) = self.frames.last_mut() else {
1741 return Err(ReflectError::OperationFailed {
1742 shape: <()>::SHAPE,
1743 operation: "tried to pop_some_push_none but there was no frame",
1744 });
1745 };
1746
1747 if frame.istate.mode != FrameMode::OptionSome {
1749 return Err(ReflectError::OperationFailed {
1750 shape: frame.shape,
1751 operation: "pop_some_push_none called, but frame was not in Option mode",
1752 });
1753 }
1754
1755 if frame.is_fully_initialized() {
1757 return Err(ReflectError::OperationFailed {
1758 shape: frame.shape,
1759 operation: "option frame already initialized, cannot pop_some_push_none",
1760 });
1761 }
1762
1763 frame.dealloc_if_needed();
1764
1765 let _frame = self.frames.pop().expect("frame already checked");
1767
1768 let parent_frame = self
1770 .frames
1771 .last_mut()
1772 .ok_or(ReflectError::OperationFailed {
1773 shape: <()>::SHAPE,
1774 operation: "tried to pop_some_push_none but there was no parent frame",
1775 })?;
1776
1777 unsafe {
1779 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1780 default_fn(parent_frame.data);
1781 } else {
1782 return Err(ReflectError::OperationFailed {
1783 shape: parent_frame.shape,
1784 operation: "option type does not implement Default",
1785 });
1786 }
1787 parent_frame.mark_fully_initialized();
1788 }
1789
1790 let Def::Option(od) = parent_frame.shape.def else {
1791 return Err(ReflectError::OperationFailed {
1792 shape: parent_frame.shape,
1793 operation: "pop_some_push_none and the parent isn't of type Option???",
1794 });
1795 };
1796
1797 let data = parent_frame.data;
1799
1800 let mut frame = Frame {
1801 data,
1802 shape: od.t(),
1803 field_index_in_parent: Some(0),
1804 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1805 };
1806 unsafe {
1807 frame.mark_fully_initialized();
1808 }
1809
1810 self.frames.push(frame);
1811
1812 Ok(self)
1813 }
1814
1815 pub fn push_map_key(mut self) -> Result<Self, ReflectError> {
1820 let frame = self.frames.last().unwrap();
1822 let map_shape = frame.shape;
1823
1824 if !matches!(map_shape.def, Def::Map(_)) {
1825 return Err(ReflectError::WasNotA {
1826 expected: "map or hash map",
1827 actual: map_shape,
1828 });
1829 }
1830
1831 if !frame.istate.fields.has(0) {
1833 self = self.begin_map_insert()?;
1834 }
1835
1836 let key_shape = self.key_shape()?;
1838
1839 let key_data = key_shape
1841 .allocate()
1842 .map_err(|_| ReflectError::Unsized { shape: key_shape })?;
1843
1844 let key_frame = Frame {
1846 data: key_data,
1847 shape: key_shape,
1848 field_index_in_parent: None,
1849 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1850 };
1851
1852 trace!(
1853 "[{}] Pushing key of type {} for map {}",
1854 self.frames.len(),
1855 key_shape.green(),
1856 map_shape.blue(),
1857 );
1858
1859 self.frames.push(key_frame);
1860 Ok(self)
1861 }
1862
1863 pub fn push_map_value(mut self) -> Result<Self, ReflectError> {
1868 trace!("Wants to push map value. Frames = ");
1869 #[cfg(feature = "log")]
1870 for (i, f) in self.frames.iter().enumerate() {
1871 trace!("Frame {}: {:?}", i, f);
1872 }
1873
1874 if self.frames.len() < 2 {
1876 return Err(ReflectError::OperationFailed {
1877 shape: <()>::SHAPE,
1878 operation: "tried to push map value but there was no key frame",
1879 });
1880 }
1881
1882 let key_frame_index = self.frames.len() - 1;
1884 let key_frame = &self.frames[key_frame_index];
1885
1886 match key_frame.istate.mode {
1888 FrameMode::MapKey => {} _ => {
1890 return Err(ReflectError::OperationFailed {
1891 shape: key_frame.shape,
1892 operation: "current frame is not a map key",
1893 });
1894 }
1895 }
1896
1897 if !key_frame.is_fully_initialized() {
1899 return Err(ReflectError::OperationFailed {
1900 shape: key_frame.shape,
1901 operation: "map key is not fully initialized",
1902 });
1903 }
1904
1905 let map_frame_index = self.frames.len() - 2;
1907 let map_frame = &self.frames[map_frame_index];
1908 let map_shape = map_frame.shape;
1909
1910 let Def::Map(map_def) = map_shape.def else {
1911 return Err(ReflectError::WasNotA {
1912 expected: "map",
1913 actual: map_frame.shape,
1914 });
1915 };
1916
1917 let value_shape = map_def.v;
1918
1919 let value_data = value_shape
1921 .allocate()
1922 .map_err(|_| ReflectError::Unsized { shape: value_shape })?;
1923
1924 let value_frame = Frame {
1926 data: value_data,
1927 shape: value_shape,
1928 field_index_in_parent: None,
1929 istate: IState::new(
1930 self.frames.len(),
1931 FrameMode::MapValue {
1932 index: key_frame_index,
1933 },
1934 FrameFlags::ALLOCATED,
1935 ),
1936 };
1937
1938 trace!(
1939 "[{}] Pushing value of type {} for map {} with key type {}",
1940 self.frames.len(),
1941 value_shape.green(),
1942 map_shape.blue(),
1943 key_frame.shape.yellow(),
1944 );
1945
1946 self.frames.push(value_frame);
1947 Ok(self)
1948 }
1949
1950 pub fn pop(mut self) -> Result<Self, ReflectError> {
1952 let frame = match self.pop_inner()? {
1953 Some(frame) => frame,
1954 None => {
1955 return Err(ReflectError::InvariantViolation {
1956 invariant: "No frame to pop — it was time to call build()",
1957 });
1958 }
1959 };
1960
1961 self.track(frame);
1962 Ok(self)
1963 }
1964
1965 fn pop_inner(&mut self) -> Result<Option<Frame>, ReflectError> {
1966 let mut frame = match self.frames.pop() {
1967 Some(f) => f,
1968 None => return Ok(None),
1969 };
1970 #[cfg(feature = "log")]
1971 let frame_shape = frame.shape;
1972
1973 let init = frame.is_fully_initialized();
1974 trace!(
1975 "[{}] {} popped, {} initialized",
1976 self.frames.len(),
1977 frame_shape.blue(),
1978 if init {
1979 "✅ fully".style(owo_colors::Style::new().green())
1980 } else {
1981 "🚧 partially".style(owo_colors::Style::new().red())
1982 }
1983 );
1984 if init {
1985 if let Some(parent) = self.frames.last_mut() {
1986 if let Some(index) = frame.field_index_in_parent {
1987 parent.istate.fields.set(index);
1988 }
1989 }
1990 }
1991
1992 match frame.istate.mode {
1994 FrameMode::ListElement => {
1996 if frame.is_fully_initialized() {
1997 #[cfg(feature = "log")]
1999 let frame_len = self.frames.len();
2000
2001 let parent_frame = self.frames.last_mut().unwrap();
2003 let parent_shape = parent_frame.shape;
2004
2005 match parent_shape.def {
2006 Def::List(list_def) => {
2008 let list_vtable = list_def.vtable;
2009 trace!(
2010 "[{}] Pushing element to list {}",
2011 frame_len,
2012 parent_shape.blue()
2013 );
2014 unsafe {
2015 (list_vtable.push)(
2016 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
2017 PtrMut::new(frame.data.as_mut_byte_ptr()),
2018 );
2019 self.mark_moved_out_of(&mut frame);
2020 }
2021 }
2022
2023 Def::Struct(sd)
2025 if sd.kind == facet_core::StructKind::Tuple && sd.fields.is_empty() =>
2026 {
2027 trace!(
2028 "[{}] Handling empty tuple struct unit type {}",
2029 frame_len,
2030 parent_shape.blue()
2031 );
2032 unsafe {
2034 parent_frame.mark_fully_initialized();
2035 }
2036 unsafe { self.mark_moved_out_of(&mut frame) };
2038 }
2039 Def::Scalar(s) if matches!(s.affinity, ScalarAffinity::Empty(_)) => {
2040 trace!(
2041 "[{}] Handling scalar empty unit type {}",
2042 frame_len,
2043 parent_shape.blue()
2044 );
2045 unsafe {
2047 parent_frame.mark_fully_initialized();
2048 self.mark_moved_out_of(&mut frame);
2049 }
2050 }
2051
2052 Def::Struct(sd) if sd.kind == facet_core::StructKind::Tuple => {
2054 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2056 let field_index = previous_index - 1; if field_index >= sd.fields.len() {
2059 panic!(
2060 "Field index {} out of bounds for tuple struct {} with {} fields",
2061 field_index,
2062 parent_shape,
2063 sd.fields.len()
2064 );
2065 }
2066
2067 let field = &sd.fields[field_index];
2068 trace!(
2069 "[{}] Setting tuple struct field {} ({}) of {}",
2070 frame_len,
2071 field_index.to_string().yellow(),
2072 field.name.bright_blue(),
2073 parent_shape.blue()
2074 );
2075
2076 unsafe {
2077 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2079 field_ptr
2080 .copy_from(
2081 PtrConst::new(frame.data.as_byte_ptr()),
2082 field.shape(),
2083 )
2084 .map_err(|_| ReflectError::Unsized {
2085 shape: field.shape(),
2086 })?; parent_frame.istate.fields.set(field_index);
2090
2091 self.mark_moved_out_of(&mut frame);
2093 }
2094 }
2095
2096 Def::Enum(_) => {
2098 let variant =
2100 parent_frame.istate.variant.as_ref().unwrap_or_else(|| {
2101 panic!(
2102 "Popping element for enum {} but no variant was selected",
2103 parent_shape
2104 )
2105 });
2106
2107 if variant.data.kind != facet_core::StructKind::Tuple {
2108 panic!(
2109 "Popping element for enum {}, but selected variant '{}' is not a tuple variant",
2110 parent_shape, variant.name
2111 );
2112 }
2113
2114 let previous_index = parent_frame.istate.list_index.unwrap_or(1);
2116 let field_index = previous_index - 1; if field_index >= variant.data.fields.len() {
2119 panic!(
2120 "Field index {} out of bounds for tuple enum variant '{}' of {} with {} fields",
2121 field_index,
2122 variant.name,
2123 parent_shape,
2124 variant.data.fields.len()
2125 );
2126 }
2127
2128 let field = &variant.data.fields[field_index];
2129 trace!(
2130 "[{}] Setting tuple enum variant field {} ({}) of variant '{}' in {}",
2131 frame_len,
2132 field_index.to_string().yellow(),
2133 field.name.bright_blue(),
2134 variant.name.yellow(),
2135 parent_shape.blue()
2136 );
2137
2138 unsafe {
2139 let field_ptr = parent_frame.data.field_uninit_at(field.offset);
2141 field_ptr
2142 .copy_from(
2143 PtrConst::new(frame.data.as_byte_ptr()),
2144 field.shape(),
2145 )
2146 .map_err(|_| ReflectError::Unsized {
2147 shape: field.shape(),
2148 })?; parent_frame.istate.fields.set(field_index);
2152
2153 self.mark_moved_out_of(&mut frame);
2155 }
2156 }
2157
2158 _ => {
2160 panic!(
2161 "FrameMode::ListElement pop expected parent to be List, Tuple Struct, or Tuple Enum Variant, but got {}",
2162 parent_shape
2163 );
2164 }
2165 }
2166 } else {
2167 trace!(
2169 "Popping uninitialized ListElement frame ({}), potential leak if allocated resources are not managed",
2170 frame.shape.yellow()
2171 );
2172 }
2173 }
2174
2175 FrameMode::MapValue {
2177 index: key_frame_index,
2178 } if frame.is_fully_initialized() => {
2179 let mut key_frame = self.frames.remove(key_frame_index);
2183
2184 if !key_frame.istate.fields.is_any_set() {
2186 panic!("key is not initialized when popping value frame");
2187 }
2188
2189 #[cfg(feature = "log")]
2191 let frame_len = self.frames.len();
2192 let parent_frame = self.frames.last_mut().unwrap();
2193 let parent_shape = parent_frame.shape;
2194
2195 match parent_shape.def {
2197 Def::Map(_) => {
2198 if let Def::Map(map_def) = parent_shape.def {
2200 trace!(
2201 "[{}] Inserting key-value pair into map {}",
2202 frame_len,
2203 parent_shape.blue()
2204 );
2205 unsafe {
2206 (map_def.vtable.insert_fn)(
2208 parent_frame.data.assume_init(),
2209 key_frame.data.assume_init(),
2210 PtrMut::new(frame.data.as_mut_byte_ptr()),
2211 );
2212 self.mark_moved_out_of(&mut key_frame);
2213 self.mark_moved_out_of(&mut frame);
2214 }
2215 } else {
2216 panic!("parent frame is not a map type");
2217 }
2218 }
2219 _ => {
2220 panic!("Expected map or hash map, got {}", frame.shape);
2221 }
2222 }
2223 }
2224
2225 FrameMode::OptionSome => {
2227 if frame.is_fully_initialized() {
2228 trace!("Popping OptionSome (fully init'd)");
2229
2230 #[cfg(feature = "log")]
2232 let frames_len = self.frames.len();
2233 let parent_frame = self.frames.last_mut().unwrap();
2234 let parent_shape = parent_frame.shape;
2235
2236 match parent_shape.def {
2238 Def::Option(option_def) => {
2239 trace!(
2240 "[{}] Setting Some value in option {}",
2241 frames_len,
2242 parent_shape.blue()
2243 );
2244 unsafe {
2245 (option_def.vtable.init_some_fn)(
2247 parent_frame.data,
2248 PtrConst::new(frame.data.as_byte_ptr()),
2249 );
2250 trace!("Marking parent frame as fully initialized");
2251 parent_frame.mark_fully_initialized();
2252
2253 self.mark_moved_out_of(&mut frame);
2254 }
2255 }
2256 _ => {
2257 panic!(
2258 "Expected parent frame to be an option type, got {}",
2259 frame.shape
2260 );
2261 }
2262 }
2263 } else {
2264 trace!("Popping OptionSome (not fully init'd)");
2265 }
2266 }
2267
2268 FrameMode::MapKey => {}
2271
2272 FrameMode::Field => {}
2274
2275 _ => {}
2277 }
2278
2279 Ok(Some(frame))
2280 }
2281
2282 pub fn evict_tree(&mut self, frame: Frame) -> Frame {
2286 match frame.shape.def {
2287 Def::Struct(sd) => {
2288 for f in sd.fields {
2289 let id = ValueId {
2290 shape: f.shape(),
2291 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
2292 };
2293 if let Some(istate) = self.istates.remove(&id) {
2294 let frame = Frame::recompose(id, istate);
2295 self.evict_tree(frame);
2296 } else {
2297 trace!("No istate found for field {}", f.name);
2298 }
2299 }
2300 }
2301 Def::Enum(_ed) => {
2302 if let Some(variant) = &frame.istate.variant {
2304 trace!(
2305 "Evicting enum {} variant '{}' fields",
2306 frame.shape.blue(),
2307 variant.name.yellow()
2308 );
2309 for field in variant.data.fields {
2311 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2313 let field_shape = field.shape();
2314 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2315
2316 if let Some(field_istate) = self.istates.remove(&field_id) {
2318 trace!(
2319 "Evicting field '{}' (shape {}) of enum variant '{}'",
2320 field.name.bright_blue(),
2321 field_shape.green(),
2322 variant.name.yellow()
2323 );
2324 let field_frame = Frame::recompose(field_id, field_istate);
2326 self.evict_tree(field_frame);
2328 } else {
2329 trace!(
2330 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
2331 field.name.red(),
2332 field_shape.red(),
2333 variant.name.yellow()
2334 );
2335 }
2336 }
2337 } else {
2338 trace!(
2340 "Enum {} has no variant selected, no fields to evict.",
2341 frame.shape.blue()
2342 );
2343 }
2344 }
2345 _ => {}
2346 }
2347 frame
2348 }
2349
2350 #[allow(rustdoc::broken_intra_doc_links)]
2351 pub fn path(&self) -> String {
2354 let mut path = String::from("$");
2355
2356 for (i, frame) in self.frames.iter().enumerate() {
2357 if i == 0 {
2359 continue;
2360 }
2361
2362 match frame.istate.mode {
2363 FrameMode::ListElement => {
2364 if let Some(index) = frame.istate.list_index {
2366 path.push_str(&format!("[{}]", index));
2367 } else {
2368 path.push_str("[?]");
2369 }
2370 }
2371 FrameMode::MapKey => {
2372 path.push_str(".key");
2373 }
2374 FrameMode::MapValue { index: _ } => {
2375 path.push_str(".value");
2376 }
2377 FrameMode::OptionSome => {
2378 path.push_str(".some");
2379 }
2380 FrameMode::OptionNone => {
2381 path.push_str(".none");
2382 }
2383 FrameMode::Root => {
2384 }
2386 FrameMode::Field => {
2387 if let Some(index) = frame.field_index_in_parent {
2389 if let Some(parent) = self.frames.get(i - 1) {
2391 if let Def::Struct(sd) = parent.shape.def {
2392 if index < sd.fields.len() {
2393 let field_name = sd.fields[index].name;
2394 path.push('.');
2395 path.push_str(field_name);
2396 }
2397 } else if let Def::Enum(_) = parent.shape.def {
2398 if let Some(variant) = &parent.istate.variant {
2399 if index < variant.data.fields.len() {
2400 let field_name = variant.data.fields[index].name;
2401 path.push('.');
2402 path.push_str(field_name);
2403 }
2404 }
2405 }
2406 }
2407 }
2408 }
2409 }
2410 }
2411
2412 path
2413 }
2414
2415 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
2417 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
2418 shape: <()>::SHAPE,
2419 operation: "tried to check if field is set, but there was no frame",
2420 })?;
2421
2422 match frame.shape.def {
2423 Def::Struct(ref sd) => {
2424 if index >= sd.fields.len() {
2425 return Err(ReflectError::FieldError {
2426 shape: frame.shape,
2427 field_error: FieldError::IndexOutOfBounds {
2428 index,
2429 bound: sd.fields.len(),
2430 },
2431 });
2432 }
2433 Ok(frame.istate.fields.has(index))
2434 }
2435 Def::Enum(_) => {
2436 let variant = frame.istate.variant.as_ref().ok_or(
2437 ReflectError::OperationFailed {
2438 shape: frame.shape,
2439 operation: "tried to check if field is set, but no variant was selected",
2440 },
2441 )?;
2442 if index >= variant.data.fields.len() {
2443 return Err(ReflectError::FieldError {
2444 shape: frame.shape,
2445 field_error: FieldError::IndexOutOfBounds {
2446 index,
2447 bound: variant.data.fields.len(),
2448 },
2449 });
2450 }
2451 Ok(frame.istate.fields.has(index))
2452 }
2453 _ => Err(ReflectError::WasNotA {
2454 expected: "struct or enum",
2455 actual: frame.shape,
2456 }),
2457 }
2458 }
2459}
2460
2461impl Drop for Wip<'_> {
2462 fn drop(&mut self) {
2463 trace!("🧹🧹🧹 WIP is dropping");
2464
2465 while let Some(frame) = self.frames.pop() {
2466 self.track(frame);
2467 }
2468
2469 let Some((root_id, _)) = self.istates.iter().find(|(_k, istate)| istate.depth == 0) else {
2470 trace!("No root found, we probably built already");
2471 return;
2472 };
2473
2474 let root_id = *root_id;
2475 let root_istate = self.istates.remove(&root_id).unwrap();
2476 let root = Frame::recompose(root_id, root_istate);
2477 let mut to_clean = vec![root];
2478
2479 let mut _root_guard: Option<Guard> = None;
2480
2481 while let Some(mut frame) = to_clean.pop() {
2482 trace!(
2483 "Cleaning frame: shape={} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
2484 frame.shape.blue(),
2485 frame.data.as_byte_ptr(),
2486 frame.istate.flags.bright_magenta(),
2487 frame.istate.mode.yellow(),
2488 if frame.is_fully_initialized() {
2489 "✅"
2490 } else {
2491 "❌"
2492 }
2493 );
2494
2495 if frame.istate.flags.contains(FrameFlags::MOVED) {
2496 trace!(
2497 "{}",
2498 "Frame was moved out of, nothing to dealloc/drop_in_place".yellow()
2499 );
2500 continue;
2501 }
2502
2503 match frame.shape.def {
2504 Def::Struct(sd) => {
2505 if frame.is_fully_initialized() {
2506 trace!(
2507 "Dropping fully initialized struct: {} at {:p}",
2508 frame.shape.green(),
2509 frame.data.as_byte_ptr()
2510 );
2511 let frame = self.evict_tree(frame);
2512 unsafe { frame.drop_and_dealloc_if_needed() };
2513 } else {
2514 let num_fields = sd.fields.len();
2515 trace!(
2516 "De-initializing struct {} at {:p} field-by-field ({} fields)",
2517 frame.shape.yellow(),
2518 frame.data.as_byte_ptr(),
2519 num_fields.to_string().bright_cyan()
2520 );
2521 for i in 0..num_fields {
2522 if frame.istate.fields.has(i) {
2523 let field = sd.fields[i];
2524 let field_shape = field.shape();
2525 let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
2526 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
2527 trace!(
2528 "Recursively cleaning field #{} '{}' of {}: field_shape={}, field_ptr={:p}",
2529 i.to_string().bright_cyan(),
2530 field.name.bright_blue(),
2531 frame.shape.blue(),
2532 field_shape.green(),
2533 field_ptr.as_byte_ptr()
2534 );
2535 let istate = self.istates.remove(&field_id).unwrap();
2536 let field_frame = Frame::recompose(field_id, istate);
2537 to_clean.push(field_frame);
2538 } else {
2539 trace!(
2540 "Field #{} '{}' of {} was NOT initialized, skipping",
2541 i.to_string().bright_cyan(),
2542 sd.fields[i].name.bright_red(),
2543 frame.shape.red()
2544 );
2545 }
2546 }
2547
2548 if frame.istate.mode == FrameMode::Root {
2550 if let Ok(layout) = frame.shape.layout.sized_layout() {
2551 _root_guard = Some(Guard {
2552 ptr: frame.data.as_mut_byte_ptr(),
2553 layout,
2554 });
2555 }
2556 }
2557 }
2558 }
2559 Def::Enum(_ed) => {
2560 trace!(
2561 "{}",
2562 format_args!(
2563 "TODO: handle enum deallocation for {} at {:p}",
2564 frame.shape.yellow(),
2565 frame.data.as_byte_ptr()
2566 )
2567 .magenta()
2568 );
2569
2570 if frame.istate.mode == FrameMode::Root {
2572 if let Ok(layout) = frame.shape.layout.sized_layout() {
2573 _root_guard = Some(Guard {
2574 ptr: frame.data.as_mut_byte_ptr(),
2575 layout,
2576 });
2577 }
2578 }
2579 }
2580 Def::Array(_)
2581 | Def::Slice(_)
2582 | Def::List(_)
2583 | Def::Map(_)
2584 | Def::SmartPointer(_)
2585 | Def::Scalar(_)
2586 | Def::FunctionPointer(_)
2587 | Def::Option(_) => {
2588 trace!(
2589 "Can drop all at once for shape {} (def variant: {:?}, frame mode {:?}) at {:p}",
2590 frame.shape.cyan(),
2591 frame.shape.def,
2592 frame.istate.mode.yellow(),
2593 frame.data.as_byte_ptr(),
2594 );
2595
2596 if frame.is_fully_initialized() {
2597 unsafe { frame.drop_and_dealloc_if_needed() }
2598 } else {
2599 frame.dealloc_if_needed();
2600 }
2601 }
2602 _ => {}
2603 }
2604 }
2605
2606 let mut all_ids = self.istates.keys().copied().collect::<Vec<_>>();
2608 for frame_id in all_ids.drain(..) {
2609 let frame_istate = self.istates.remove(&frame_id).unwrap();
2610
2611 trace!(
2612 "Checking leftover istate: id.shape={} id.ptr={:p} mode={:?}",
2613 frame_id.shape.cyan(),
2614 frame_id.ptr,
2615 frame_istate.mode.yellow()
2616 );
2617 let mut frame = Frame::recompose(frame_id, frame_istate);
2618
2619 if frame.is_fully_initialized() {
2620 trace!("It's fully initialized, we can drop it");
2621 unsafe { frame.drop_and_dealloc_if_needed() };
2622 } else if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
2623 trace!("Not initialized but allocated, let's free it");
2624 frame.dealloc_if_needed();
2625 }
2626 }
2627 }
2628}
2629
2630impl core::fmt::Debug for Wip<'_> {
2631 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2632 struct TypeName(TypeNameFn);
2633 impl core::fmt::Display for TypeName {
2634 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2635 self.0(f, TypeNameOpts::default())
2636 }
2637 }
2638 impl TypeName {
2639 fn new(frame: &Frame) -> Self {
2640 Self(frame.shape.vtable.type_name)
2641 }
2642 }
2643
2644 let frames_dbg = self
2645 .frames
2646 .iter()
2647 .zip(self.frames.iter().skip(1))
2648 .map(|(frame, next_frame)| {
2649 let Some(index) = next_frame.field_index_in_parent else {
2650 return "(Child frame has no parent)".to_string();
2651 };
2652 let shape = frame.shape;
2653 let field = match shape.def {
2654 Def::Struct(def) => {
2655 if index >= def.fields.len() {
2656 return format!("(Field {index} out of bounds)");
2657 }
2658 &def.fields[index]
2659 }
2660 Def::Enum(_) => {
2661 let Some(variant) = frame.istate.variant.as_ref() else {
2662 return "(Enum without variant selected)".to_string();
2663 };
2664
2665 if index >= variant.data.fields.len() {
2666 return format!("(Enum {index} out of bounds)");
2667 }
2668
2669 &variant.data.fields[index]
2670 }
2671 _ => {
2672 return "(Expected parent frame to be a struct or enum)".to_string();
2673 }
2674 };
2675 field.name.to_string()
2676 })
2677 .collect::<Vec<_>>()
2678 .join(".");
2679
2680 let fmt_tyname = |optty: Option<TypeName>| {
2681 optty
2682 .map(|ty| ty.to_string())
2683 .unwrap_or_else(|| "AAA WIP WITHOUT FRAMES AAAAA".to_string())
2684 };
2685 let outermost_tyname = self.frames.first().map(TypeName::new);
2686 let innermost_tyname = self.frames.last().map(TypeName::new);
2687 let cursor = format!(
2688 "{}{}{} ({})",
2689 fmt_tyname(outermost_tyname),
2690 if frames_dbg.is_empty() { "" } else { "." },
2691 frames_dbg,
2692 fmt_tyname(innermost_tyname),
2693 );
2694 f.debug_struct("Wip").field("cursor", &cursor).finish()
2695 }
2696}