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
8mod drop;
9mod pop;
10
11mod frame;
12pub(crate) use frame::*;
13
14use alloc::format;
15use bitflags::bitflags;
16use core::marker::PhantomData;
17use facet_core::{
18 Def, DefaultInPlaceFn, Facet, FieldError, PtrConst, PtrUninit, ScalarAffinity, SequenceType,
19 Shape, Type, UserType, Variant,
20};
21use flat_map::FlatMap;
22
23use alloc::string::String;
24
25mod iset;
26pub use iset::*;
27
28mod put_f64;
29mod put_shape;
30
31mod enum_;
32mod flat_map;
33
34mod heap_value;
35pub use heap_value::*;
36
37pub(crate) struct IState<'shape> {
39 variant: Option<Variant<'shape>>,
41
42 fields: ISet,
44
45 depth: usize,
47
48 mode: FrameMode,
50
51 flags: FrameFlags,
53
54 list_index: Option<usize>,
56
57 #[allow(dead_code)]
59 map_key: Option<String>,
60}
61
62bitflags! {
63 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
65 pub struct FrameFlags: u64 {
66 const EMPTY = 0;
68
69 const ALLOCATED = 1 << 0;
71
72 const MOVED = 1 << 1;
76 }
77
78 }
80
81impl<'shape> IState<'shape> {
82 pub fn new(depth: usize, mode: FrameMode, flags: FrameFlags) -> Self {
84 Self {
85 variant: None,
86 fields: Default::default(),
87 depth,
88 mode,
89 flags,
90 list_index: None,
91 map_key: None,
92 }
93 }
94
95 #[allow(dead_code)]
97 pub fn with_list_index(mut self, index: usize) -> Self {
98 self.list_index = Some(index);
99 self
100 }
101
102 #[allow(dead_code)]
104 pub fn with_map_key(mut self, key: String) -> Self {
105 self.map_key = Some(key);
106 self
107 }
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub enum FrameMode {
113 Root,
115 Field,
117 ListElement,
119 MapKey,
121 MapValue {
123 index: usize,
125 },
126 OptionSome,
128 OptionNone,
131 SmartPointee,
133}
134
135pub struct Wip<'facet, 'shape> {
142 frames: alloc::vec::Vec<Frame<'shape>>,
144
145 istates: FlatMap<ValueId<'shape>, IState<'shape>>,
147
148 invariant: PhantomData<fn(&'facet ()) -> &'facet ()>,
149}
150
151impl<'facet, 'shape> Wip<'facet, 'shape> {
152 pub fn put_peek(
154 self,
155 peek: crate::Peek<'_, 'facet, 'shape>,
156 ) -> Result<Wip<'facet, 'shape>, ReflectError<'shape>> {
157 self.put_shape(peek.data, peek.shape)
158 }
159
160 pub fn frames_count(&self) -> usize {
162 self.frames.len()
163 }
164
165 pub fn alloc_shape(shape: &'shape Shape<'shape>) -> Result<Self, ReflectError<'shape>> {
167 let data = shape
168 .allocate()
169 .map_err(|_| ReflectError::Unsized { shape })?;
170 Ok(Self {
171 frames: alloc::vec![Frame {
172 data,
173 shape,
174 field_index_in_parent: None,
175 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
176 }],
177 istates: Default::default(),
178 invariant: PhantomData,
179 })
180 }
181
182 pub fn alloc<S: Facet<'facet>>() -> Result<Self, ReflectError<'shape>> {
184 Self::alloc_shape(S::SHAPE)
185 }
186
187 fn track(&mut self, frame: Frame<'shape>) {
188 if frame.istate.flags.contains(FrameFlags::MOVED) {
194 return;
196 }
197
198 self.istates.insert(frame.id(), frame.istate);
199 }
200
201 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame<'shape>) {
202 unsafe fn mark_subtree_moved<'facet, 'shape>(
205 wip: &mut Wip<'facet, 'shape>,
206 id: ValueId<'shape>,
207 ) {
208 unsafe {
210 if let Some(mut istate) = wip.istates.remove(&id) {
212 istate.flags.insert(FrameFlags::MOVED);
214
215 match id.shape.ty {
217 Type::User(UserType::Struct(sd)) => {
218 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
219 for field in sd.fields.iter() {
220 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
221 let field_id =
222 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
223 mark_subtree_moved(wip, field_id);
225 }
226 }
227 Type::User(UserType::Enum(_)) => {
228 if let Some(variant) = &istate.variant {
230 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
231 for field in variant.data.fields.iter() {
232 let field_ptr_uninit =
233 container_ptr.field_uninit_at(field.offset);
234 let field_id =
235 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
236 mark_subtree_moved(wip, field_id);
238 }
239 }
240 }
241 _ => {}
245 }
246
247 if istate.flags.contains(FrameFlags::ALLOCATED) {
250 let mut temp_frame = Frame::recompose(id, istate);
252 temp_frame.dealloc_if_needed();
253 }
254 }
255 }
257 }
258
259 unsafe {
262 let frame_id = frame.id();
264
265 let variant_opt = frame.istate.variant;
267
268 frame.istate.flags.insert(FrameFlags::MOVED);
270 ISet::clear(&mut frame.istate.fields);
271
272 match frame.shape.ty {
275 Type::User(UserType::Struct(sd)) => {
276 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
277 for field in sd.fields.iter() {
278 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
279 let field_id = ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
280 mark_subtree_moved(self, field_id);
281 }
282 }
283 Type::User(UserType::Enum(_)) => {
284 if let Some(variant) = &variant_opt {
286 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
287 for field in variant.data.fields.iter() {
288 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
289 let field_id =
290 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
291 mark_subtree_moved(self, field_id);
292 }
293 }
294 }
295 _ => {}
297 }
298
299 frame.istate.variant = None;
301
302 self.istates.remove(&frame_id);
304
305 if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
307 frame.dealloc_if_needed();
308 }
309 }
310 }
311
312 pub fn shape(&self) -> &'shape Shape<'shape> {
314 self.frames.last().expect("must have frames left").shape
315 }
316
317 pub fn innermost_shape(&self) -> &'shape Shape<'shape> {
321 let mut current_shape = self.shape();
322
323 while let Some(inner_fn) = current_shape.inner {
325 current_shape = inner_fn();
326 }
327
328 current_shape
329 }
330
331 pub fn in_option(&self) -> bool {
333 let Some(frame) = self.frames.last() else {
334 return false;
335 };
336 matches!(frame.istate.mode, FrameMode::OptionSome)
337 }
338
339 pub fn mode(&self) -> FrameMode {
341 self.frames.last().unwrap().istate.mode
342 }
343
344 pub fn build(mut self) -> Result<HeapValue<'facet, 'shape>, ReflectError<'shape>> {
346 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
347
348 if self.frames.is_empty() {
350 panic!("No frames in WIP during build: stack is empty (you popped too much)");
351 }
352 if self.frames.len() != 1 {
353 panic!(
354 "You must pop frames so that only the root frame remains before calling build (frames left: {})",
355 self.frames.len()
356 );
357 }
358
359 let root_frame = &self.frames[0];
361
362 enum FrameRef<'shape> {
363 Root,
364 ById(ValueId<'shape>),
365 }
366 let mut to_check = alloc::vec![FrameRef::Root];
367
368 while let Some(fr) = to_check.pop() {
370 let (id, istate) = match fr {
371 FrameRef::Root => (root_frame.id(), &root_frame.istate),
372 FrameRef::ById(id) => {
373 let istate = self.istates.get(&id).unwrap();
375 (id, istate)
376 }
377 };
378
379 trace!(
380 "Checking shape {} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
381 id.shape.blue(),
382 id.ptr,
383 istate.flags.bright_magenta(),
384 istate.mode.yellow(),
385 if is_fully_initialized(id.shape, istate) {
386 "✅"
387 } else {
388 "❌"
389 }
390 );
391
392 if istate.flags.contains(FrameFlags::MOVED) {
394 trace!(
395 "{}",
396 "Frame was moved out of, skipping initialization check".yellow()
397 );
398 continue;
399 }
400
401 if let Def::Array(array_def) = id.shape.def {
405 let pushed_count = istate.list_index.unwrap_or(0);
407
408 if pushed_count != array_def.n {
410 return Err(ReflectError::ArrayNotFullyInitialized {
411 shape: id.shape,
412 pushed_count,
413 expected_size: array_def.n,
414 });
415 }
416 }
417 else if !matches!(id.shape.def, Def::Undefined) {
421 if !istate.fields.are_all_set(1) {
422 match istate.mode {
424 FrameMode::OptionNone => {
425 debug!("Found uninitialized value (option none) — {}", id.shape);
427 return Err(ReflectError::UninitializedValue { shape: id.shape });
428 }
429 _ => {
431 debug!(
432 "Found uninitialized value (list/map/option/etc. — {})",
433 id.shape
434 );
435 return Err(ReflectError::UninitializedValue { shape: id.shape });
436 }
437 }
438 }
439 } else {
447 match id.shape.ty {
448 Type::User(UserType::Struct(sd)) => {
449 for i in 0..sd.fields.len() {
451 if !istate.fields.has(i) {
452 let field = &sd.fields[i];
453 trace!("Found uninitialized field: {}", field.name);
454 return Err(ReflectError::UninitializedField {
455 shape: id.shape,
456 field_name: field.name,
457 });
458 }
459 }
460
461 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
462
463 #[allow(clippy::unused_enumerate_index)]
465 for (_i, field) in sd.fields.iter().enumerate() {
466 let field_shape = field.shape();
467 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
468 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
469
470 if self.istates.contains_key(&field_id) {
471 debug!(
472 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
473 _i.to_string().bright_cyan(),
474 field.name.bright_blue(),
475 id.shape.blue(),
476 field_shape.green(),
477 field_ptr.as_byte_ptr()
478 );
479 to_check.push(FrameRef::ById(field_id));
480 }
481 }
482 }
483 Type::User(UserType::Enum(_ed)) => {
484 if let Some(variant) = &istate.variant {
485 for (i, field) in variant.data.fields.iter().enumerate() {
487 if !istate.fields.has(i) {
488 trace!("Found uninitialized field: {}", field.name);
489 return Err(ReflectError::UninitializedEnumField {
490 shape: id.shape,
491 variant_name: variant.name,
492 field_name: field.name,
493 });
494 }
495 }
496
497 #[allow(clippy::unused_enumerate_index)]
499 for (_i, field) in variant.data.fields.iter().enumerate() {
500 let field_shape = field.shape();
501 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
502 let field_ptr =
504 unsafe { container_ptr.field_init_at(field.offset) };
505 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
506
507 if self.istates.contains_key(&field_id) {
508 debug!(
509 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
510 _i.to_string().bright_cyan(),
511 field.name.bright_blue(),
512 variant.name.yellow(),
513 id.shape.blue(),
514 field_shape.green(),
515 field_ptr.as_byte_ptr()
516 );
517 to_check.push(FrameRef::ById(field_id));
518 }
519 }
520 } else {
521 debug!("Found no variant selected for enum");
523 return Err(ReflectError::NoVariantSelected { shape: id.shape });
524 }
525 }
526 _ => {
528 if !istate.fields.are_all_set(1) {
530 debug!("Found uninitialized value (other)");
531 return Err(ReflectError::UninitializedValue { shape: id.shape });
532 }
533 }
534 }
535 }
536 }
537
538 debug!("All reachable frames checked and initialized.");
540
541 let root_shape = root_frame.shape;
544 let root_data = unsafe { root_frame.data.assume_init() };
545 if let Some(invariant_fn) = root_shape.vtable.invariants {
546 debug!(
547 "Checking invariants for root shape {} at {:p}",
548 root_shape.green(),
549 root_data.as_byte_ptr()
550 );
551 if !unsafe { invariant_fn(PtrConst::new(root_data.as_byte_ptr())) } {
552 return Err(ReflectError::InvariantViolation {
553 invariant: "Custom validation function returned false",
554 });
555 }
556 } else {
557 debug!(
558 "No invariants to check for root shape {}",
559 root_shape.blue()
560 );
561 }
562
563 {
565 FlatMap::clear(&mut self.istates);
566 self.frames.clear();
567 }
568
569 let guard = Guard {
571 ptr: root_data.as_mut_byte_ptr(),
572 layout: match root_shape.layout {
573 facet_core::ShapeLayout::Sized(layout) => layout,
574 facet_core::ShapeLayout::Unsized => panic!("Unsized layout not supported"),
575 },
576 };
577
578 Ok(HeapValue {
579 guard: Some(guard),
580 shape: root_shape,
581 phantom: PhantomData,
582 })
583 }
584
585 pub fn field(mut self, index: usize) -> Result<Self, ReflectError<'shape>> {
597 let frame = self.frames.last_mut().unwrap();
598 let shape = frame.shape;
599
600 let (field, field_offset) = match shape.ty {
601 Type::User(UserType::Struct(def)) => {
602 if index >= def.fields.len() {
603 return Err(ReflectError::FieldError {
604 shape,
605 field_error: FieldError::NoSuchField,
606 });
607 }
608 let field = &def.fields[index];
609 (field, field.offset)
610 }
611 Type::User(UserType::Enum(_)) => {
612 let Some(variant) = frame.istate.variant.as_ref() else {
613 return Err(ReflectError::OperationFailed {
614 shape,
615 operation: "tried to access a field but no variant was selected",
616 });
617 };
618
619 if index >= variant.data.fields.len() {
620 return Err(ReflectError::FieldError {
621 shape,
622 field_error: FieldError::NoSuchField,
623 });
624 }
625
626 let field = &variant.data.fields[index];
627 (field, field.offset)
628 }
629 _ => {
630 return Err(ReflectError::WasNotA {
631 expected: "struct or enum",
632 actual: shape,
633 });
634 }
635 };
636
637 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
638
639 let mut frame = Frame {
640 data: field_data,
641 shape: field.shape(),
642 field_index_in_parent: Some(index),
643 istate: IState::new(self.frames.len(), FrameMode::Field, FrameFlags::EMPTY),
645 };
646
647 debug!(
648 "[{}] Selecting field {}::{}: {} (#{})",
649 self.frames.len(),
650 shape.blue(),
651 field.name.yellow(),
652 field.shape().green(),
653 index.yellow(),
654 );
655 if let Some(iset) = self.istates.remove(&frame.id()) {
656 trace!(
657 "[{}] Restoring saved state for {}::{}: {} (#{}) (istate.mode = {:?}, istate.fields = {:?}, istate.flags = {:?}, istate.depth = {:?})",
658 self.frames.len(),
659 shape.blue(),
660 field.name.yellow(),
661 field.shape().green(),
662 index.yellow(),
663 iset.mode,
664 iset.fields,
665 iset.flags,
666 iset.depth
667 );
668 frame.istate = iset;
669 }
670 self.frames.push(frame);
671
672 Ok(self)
673 }
674
675 pub fn field_index(&self, name: &str) -> Option<usize> {
687 fn find_field_index(fields: &[facet_core::Field], name: &str) -> Option<usize> {
688 fields.iter().position(|f| f.name == name)
689 }
690
691 let frame = self.frames.last()?;
692 match frame.shape.ty {
693 Type::User(UserType::Struct(def)) => find_field_index(def.fields, name),
694 Type::User(UserType::Enum(_)) => {
695 let variant = frame.istate.variant.as_ref()?;
696 find_field_index(variant.data.fields, name)
697 }
698 _ => None,
699 }
700 }
701
702 pub fn field_named(self, name: &str) -> Result<Self, ReflectError<'shape>> {
714 let frame = self.frames.last().unwrap();
715 let shape = frame.shape;
716
717 if let Type::User(UserType::Enum(_)) = shape.ty {
719 if frame.istate.variant.is_none() {
720 return Err(ReflectError::OperationFailed {
721 shape,
722 operation: "tried to access a field by name but no variant was selected",
723 });
724 }
725 }
726
727 if let Def::SmartPointer(_) = shape.def {
729 return Err(ReflectError::MissingPushPointee { shape });
731 }
732
733 let index = self.field_index(name).ok_or(ReflectError::FieldError {
734 shape,
735 field_error: FieldError::NoSuchField,
736 })?;
737
738 self.field(index)
739 }
740
741 pub fn put<T: Facet<'facet>>(self, t: T) -> Result<Wip<'facet, 'shape>, ReflectError<'shape>> {
752 let shape = T::SHAPE;
753 let ptr_const = PtrConst::new(&t as *const T as *const u8);
754 let res = self.put_shape(ptr_const, shape);
755 core::mem::forget(t); res
757 }
758
759 pub fn try_put<T: Facet<'facet>>(
770 self,
771 t: T,
772 ) -> Result<Wip<'facet, 'shape>, ReflectError<'shape>> {
773 let shape = T::SHAPE;
774 let ptr_const = PtrConst::new(&t as *const T as *const u8);
775 let res = self.put_shape(ptr_const, shape);
776 core::mem::forget(t); res
778 }
779
780 pub fn parse<'ínput>(mut self, s: &'ínput str) -> Result<Self, ReflectError<'shape>> {
782 let Some(frame) = self.frames.last_mut() else {
783 return Err(ReflectError::OperationFailed {
784 shape: <()>::SHAPE,
785 operation: "tried to parse value but there was no frame",
786 });
787 };
788
789 let shape = frame.shape;
790 let index = frame.field_index_in_parent;
791
792 let Some(parse_fn) = frame.shape.vtable.parse else {
793 return Err(ReflectError::OperationFailed {
794 shape: frame.shape,
795 operation: "type does not implement Parse",
796 });
797 };
798 match unsafe { (parse_fn)(s, frame.data) } {
799 Ok(_res) => {
800 unsafe {
801 frame.mark_fully_initialized();
802 }
803
804 self.mark_field_as_initialized(shape, index)?;
806
807 Ok(self)
808 }
809 Err(_) => Err(ReflectError::OperationFailed {
810 shape,
811 operation: "parsing",
812 }),
813 }
814 }
815
816 pub fn put_from_fn(
818 mut self,
819 default_in_place: DefaultInPlaceFn,
820 ) -> Result<Self, ReflectError<'shape>> {
821 let Some(frame) = self.frames.last_mut() else {
822 return Err(ReflectError::OperationFailed {
823 shape: <()>::SHAPE,
824 operation: "tried to put value from fn but there was no frame",
825 });
826 };
827
828 if let Def::Array(array_def) = frame.shape.def {
831 trace!(
832 "[{}] Setting array as default-initialized with {} elements",
833 frame.istate.depth, array_def.n
834 );
835 frame.istate.list_index = Some(array_def.n);
837 }
838
839 unsafe {
840 default_in_place(frame.data);
841 frame.mark_fully_initialized();
842 }
843
844 let shape = frame.shape;
845 let index = frame.field_index_in_parent;
846
847 self.mark_field_as_initialized(shape, index)?;
849
850 Ok(self)
851 }
852
853 pub fn put_default(self) -> Result<Self, ReflectError<'shape>> {
855 let Some(frame) = self.frames.last() else {
856 return Err(ReflectError::OperationFailed {
857 shape: <()>::SHAPE,
858 operation: "tried to put default value but there was no frame",
859 });
860 };
861
862 let vtable = frame.shape.vtable;
863 let Some(default_in_place) = vtable.default_in_place else {
864 return Err(ReflectError::OperationFailed {
865 shape: frame.shape,
866 operation: "type does not implement Default",
867 });
868 };
869
870 self.put_from_fn(default_in_place)
871 }
872
873 fn mark_field_as_initialized(
875 &mut self,
876 shape: &'shape Shape<'shape>,
877 index: Option<usize>,
878 ) -> Result<(), ReflectError<'shape>> {
879 if let Some(index) = index {
880 let parent_index = self.frames.len().saturating_sub(2);
881 #[cfg(feature = "log")]
882 let num_frames = self.frames.len();
883 let Some(parent) = self.frames.get_mut(parent_index) else {
884 return Err(ReflectError::OperationFailed {
885 shape,
886 operation: "was supposed to mark a field as initialized, but there was no parent frame",
887 });
888 };
889 #[cfg(feature = "log")]
890 let parent_shape = parent.shape;
891 trace!(
892 "[{}] {}.{} initialized with {}",
893 num_frames,
894 parent_shape.blue(),
895 index.yellow(),
896 shape.green()
897 );
898
899 if matches!(parent.shape.ty, Type::User(UserType::Enum(_)))
900 && parent.istate.variant.is_none()
901 {
902 return Err(ReflectError::OperationFailed {
903 shape,
904 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
905 });
906 }
907
908 if parent.istate.fields.has(index) {
909 return Err(ReflectError::OperationFailed {
910 shape,
911 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
912 });
913 }
914
915 parent.istate.fields.set(index);
916 }
917 Ok(())
918 }
919
920 pub fn element_shape(&self) -> Result<&'shape Shape<'shape>, ReflectError<'shape>> {
922 let frame = self.frames.last().unwrap();
923 let shape = frame.shape;
924
925 match shape.def {
926 Def::List(list_def) => Ok(list_def.t()),
927 _ => Err(ReflectError::WasNotA {
928 expected: "list or array",
929 actual: shape,
930 }),
931 }
932 }
933
934 pub fn key_shape(&self) -> Result<&'shape Shape<'shape>, ReflectError<'shape>> {
936 let frame = self.frames.last().unwrap();
937 let shape = frame.shape;
938
939 match shape.def {
940 Def::Map(map_def) => Ok(map_def.k()),
941 _ => Err(ReflectError::WasNotA {
942 expected: "map",
943 actual: shape,
944 }),
945 }
946 }
947
948 pub fn put_empty_list(mut self) -> Result<Self, ReflectError<'shape>> {
950 let Some(frame) = self.frames.last_mut() else {
951 return Err(ReflectError::OperationFailed {
952 shape: <()>::SHAPE,
953 operation: "tried to create empty list but there was no frame",
954 });
955 };
956
957 if !matches!(frame.shape.def, Def::List(_)) {
958 return Err(ReflectError::WasNotA {
959 expected: "list or array",
960 actual: frame.shape,
961 });
962 }
963
964 let vtable = frame.shape.vtable;
965
966 let Some(default_in_place) = vtable.default_in_place else {
968 return Err(ReflectError::OperationFailed {
969 shape: frame.shape,
970 operation: "list type does not implement Default",
971 });
972 };
973
974 unsafe {
975 default_in_place(frame.data);
976 frame.mark_fully_initialized();
977 }
978
979 let shape = frame.shape;
980 let index = frame.field_index_in_parent;
981
982 self.mark_field_as_initialized(shape, index)?;
984
985 Ok(self)
986 }
987
988 pub fn put_empty_map(mut self) -> Result<Self, ReflectError<'shape>> {
990 let Some(frame) = self.frames.last_mut() else {
991 return Err(ReflectError::OperationFailed {
992 shape: <()>::SHAPE,
993 operation: "tried to create empty map but there was no frame",
994 });
995 };
996
997 if !matches!(frame.shape.def, Def::Map(_)) {
998 return Err(ReflectError::WasNotA {
999 expected: "map or hash map",
1000 actual: frame.shape,
1001 });
1002 }
1003
1004 let vtable = frame.shape.vtable;
1005
1006 let Some(default_in_place) = vtable.default_in_place else {
1008 return Err(ReflectError::OperationFailed {
1009 shape: frame.shape,
1010 operation: "map type does not implement Default",
1011 });
1012 };
1013
1014 unsafe {
1015 default_in_place(frame.data);
1016 frame.mark_fully_initialized();
1017 }
1018
1019 if let Some(index) = frame.field_index_in_parent {
1021 let parent_index = self.frames.len().saturating_sub(2);
1022 if let Some(parent) = self.frames.get_mut(parent_index) {
1023 parent.istate.fields.set(index);
1024 }
1025 }
1026
1027 Ok(self)
1028 }
1029
1030 pub fn begin_pushback(mut self) -> Result<Self, ReflectError<'shape>> {
1035 let Some(frame) = self.frames.last_mut() else {
1036 return Err(ReflectError::OperationFailed {
1037 shape: <()>::SHAPE,
1038 operation: "tried to begin pushback but there was no frame",
1039 });
1040 };
1041
1042 let is_list = matches!(frame.shape.def, Def::List(_));
1043 let is_array = matches!(frame.shape.def, Def::Array(_));
1044 let is_tuple_struct_or_variant = match (frame.shape.ty, frame.shape.def) {
1045 (_, Def::Scalar(sd)) => matches!(sd.affinity, ScalarAffinity::Empty(_)),
1046 (Type::Sequence(_), _) => true,
1047 (Type::User(UserType::Struct(sd)), _) => sd.kind == facet_core::StructKind::Tuple,
1048 (Type::User(UserType::Enum(_)), _) => {
1049 if let Some(variant) = &frame.istate.variant {
1051 variant.data.kind == facet_core::StructKind::Tuple
1052 } else {
1053 false }
1062 }
1063 _ => false,
1064 };
1065
1066 if !is_list && !is_array && !is_tuple_struct_or_variant {
1067 return Err(ReflectError::WasNotA {
1068 expected: "list, array, or tuple-like struct/enum variant",
1069 actual: frame.shape,
1070 });
1071 }
1072
1073 if is_list {
1075 let vtable = frame.shape.vtable;
1076 if !frame.istate.fields.has(0) {
1078 let Some(default_in_place) = vtable.default_in_place else {
1079 return Err(ReflectError::OperationFailed {
1080 shape: frame.shape,
1081 operation: "list type does not implement Default, cannot begin pushback",
1082 });
1083 };
1084
1085 unsafe {
1086 default_in_place(frame.data);
1087 frame.istate.fields.set(0);
1089 }
1090 }
1091 }
1092 else if is_array {
1094 frame.istate.list_index = Some(0);
1096 }
1097 Ok(self)
1100 }
1101
1102 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError<'shape>> {
1104 let Some(frame) = self.frames.last_mut() else {
1105 return Err(ReflectError::OperationFailed {
1106 shape: <()>::SHAPE,
1107 operation: "tried to begin map insertion but there was no frame",
1108 });
1109 };
1110
1111 if !matches!(frame.shape.def, Def::Map(_)) {
1112 return Err(ReflectError::WasNotA {
1113 expected: "map or hash map",
1114 actual: frame.shape,
1115 });
1116 }
1117
1118 let vtable = frame.shape.vtable;
1119
1120 if !frame.istate.fields.has(0) {
1122 let Some(default_in_place) = vtable.default_in_place else {
1123 return Err(ReflectError::OperationFailed {
1124 shape: frame.shape,
1125 operation: "map type does not implement Default",
1126 });
1127 };
1128
1129 unsafe {
1130 default_in_place(frame.data);
1131 frame.istate.fields.set(0);
1132 }
1133 }
1134
1135 Ok(self)
1136 }
1137
1138 pub fn push(mut self) -> Result<Self, ReflectError<'shape>> {
1143 let frame_len = self.frames.len();
1145 let frame = self
1146 .frames
1147 .last_mut()
1148 .ok_or(ReflectError::OperationFailed {
1149 shape: <()>::SHAPE,
1150 operation: "tried to push but there was no frame",
1151 })?;
1152 let seq_shape = frame.shape;
1153
1154 let (element_shape, context_str): (&'shape Shape<'shape>, &'shape str) =
1156 match (seq_shape.ty, seq_shape.def) {
1157 (_, Def::List(list_def)) => {
1158 if !frame.istate.fields.has(0) {
1160 return self.begin_pushback()?.push();
1163 }
1164 let shape = list_def.t();
1166 (shape, "list")
1167 }
1168 (_, Def::Array(array_def)) => {
1169 let index = frame.istate.list_index.unwrap_or(0);
1171
1172 if index >= array_def.n {
1174 return Err(ReflectError::ArrayIndexOutOfBounds {
1175 shape: seq_shape,
1176 index,
1177 size: array_def.n,
1178 });
1179 }
1180
1181 frame.istate.list_index = Some(index + 1);
1183
1184 let element_shape = array_def.t;
1186 (element_shape, "array")
1187 }
1188 (Type::Sequence(SequenceType::Tuple(tt)), _) => {
1189 let field_index = {
1191 let next_idx = frame.istate.list_index.unwrap_or(0);
1193 frame.istate.list_index = Some(next_idx + 1);
1194 next_idx
1195 };
1196 if field_index >= tt.fields.len() {
1198 return Err(ReflectError::FieldError {
1199 shape: seq_shape,
1200 field_error: FieldError::NoSuchField,
1201 });
1202 }
1203 (tt.fields[field_index].shape(), "tuple")
1205 }
1206 (Type::User(UserType::Struct(sd)), _)
1207 if sd.kind == facet_core::StructKind::Tuple =>
1208 {
1209 let field_index = {
1211 let next_idx = frame.istate.list_index.unwrap_or(0);
1213 frame.istate.list_index = Some(next_idx + 1);
1214 next_idx
1215 };
1216 if field_index >= sd.fields.len() {
1218 return Err(ReflectError::FieldError {
1219 shape: seq_shape,
1220 field_error: FieldError::NoSuchField, });
1222 }
1223 (sd.fields[field_index].shape(), "tuple struct")
1225 }
1226
1227 (Type::User(UserType::Enum(_)), _) => {
1228 let variant =
1230 frame
1231 .istate
1232 .variant
1233 .as_ref()
1234 .ok_or(ReflectError::OperationFailed {
1235 shape: seq_shape,
1236 operation: "tried to push onto enum but no variant was selected",
1237 })?;
1238 if variant.data.kind != facet_core::StructKind::Tuple {
1240 return Err(ReflectError::WasNotA {
1241 expected: "tuple-like enum variant",
1242 actual: seq_shape, });
1244 }
1245 let field_index = {
1247 let next_idx = frame.istate.list_index.unwrap_or(0);
1249 frame.istate.list_index = Some(next_idx + 1);
1250 next_idx
1251 };
1252 if field_index >= variant.data.fields.len() {
1254 return Err(ReflectError::FieldError {
1255 shape: seq_shape, field_error: FieldError::NoSuchField,
1257 });
1258 }
1259 (
1261 variant.data.fields[field_index].shape(),
1262 "tuple enum variant",
1263 )
1264 }
1265 (_, Def::Scalar(sd)) if matches!(sd.affinity, ScalarAffinity::Empty(_)) => {
1266 return Err(ReflectError::OperationFailed {
1268 shape: seq_shape,
1269 operation: "cannot push elements to unit type ()",
1270 });
1271 }
1272 _ => {
1273 return Err(ReflectError::WasNotA {
1275 expected: "list, array, tuple, tuple struct, or tuple enum variant",
1276 actual: seq_shape,
1277 });
1278 }
1279 };
1280
1281 let element_data = element_shape
1283 .allocate()
1284 .map_err(|_| ReflectError::Unsized {
1285 shape: element_shape,
1286 })?;
1287
1288 let element_frame = Frame {
1290 data: element_data,
1291 shape: element_shape,
1292 field_index_in_parent: None, istate: IState::new(
1294 frame_len, FrameMode::ListElement, FrameFlags::ALLOCATED,
1297 ),
1298 };
1299
1300 trace!(
1301 "[{}] Pushing element of type {} to {} {}",
1302 frame_len,
1303 element_shape.green(),
1304 context_str, seq_shape.blue(),
1306 );
1307 let _ = context_str;
1308
1309 self.frames.push(element_frame);
1310 Ok(self)
1311 }
1312
1313 pub fn push_some(mut self) -> Result<Self, ReflectError<'shape>> {
1315 let frame = self.frames.last().unwrap();
1317 let option_shape = frame.shape;
1318
1319 let Def::Option(option_def) = option_shape.def else {
1321 return Err(ReflectError::WasNotA {
1322 expected: "option",
1323 actual: option_shape,
1324 });
1325 };
1326
1327 let inner_shape = option_def.t();
1329
1330 let inner_data = inner_shape
1332 .allocate()
1333 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1334
1335 let inner_frame = Frame {
1337 data: inner_data,
1338 shape: inner_shape,
1339 field_index_in_parent: None,
1341 istate: IState::new(
1342 self.frames.len(),
1343 FrameMode::OptionSome,
1344 FrameFlags::ALLOCATED,
1346 ),
1347 };
1348
1349 trace!(
1350 "[{}] Pushing option frame for {}",
1351 self.frames.len(),
1352 option_shape.blue(),
1353 );
1354
1355 self.frames.push(inner_frame);
1356 Ok(self)
1357 }
1358
1359 pub fn push_pointee(mut self) -> Result<Self, ReflectError<'shape>> {
1363 let frame = self.frames.last().unwrap();
1365 let smart_ptr_shape = frame.shape;
1366
1367 let Def::SmartPointer(smart_ptr_def) = smart_ptr_shape.def else {
1369 return Err(ReflectError::WasNotA {
1370 expected: "smart pointer (pointee type)",
1371 actual: smart_ptr_shape,
1372 });
1373 };
1374
1375 let Some(pointee_fn) = smart_ptr_def.pointee else {
1377 return Err(ReflectError::OperationFailed {
1378 shape: smart_ptr_shape,
1379 operation: "smart pointer does not specify a pointee type",
1380 });
1381 };
1382 let inner_shape = pointee_fn();
1383
1384 let inner_data = inner_shape
1386 .allocate()
1387 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1388
1389 let inner_frame = Frame {
1391 data: inner_data,
1392 shape: inner_shape,
1393 field_index_in_parent: None, istate: IState::new(
1395 self.frames.len(),
1396 FrameMode::SmartPointee, FrameFlags::ALLOCATED,
1398 ),
1399 };
1400
1401 trace!(
1402 "[{}] Pushing smart pointer pointee frame for {}",
1403 self.frames.len(),
1404 smart_ptr_shape.blue(),
1405 );
1406
1407 self.frames.push(inner_frame);
1408
1409 Ok(self)
1410 }
1411
1412 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError<'shape>> {
1422 let Some(frame) = self.frames.last_mut() else {
1424 return Err(ReflectError::OperationFailed {
1425 shape: <()>::SHAPE,
1426 operation: "tried to pop_some_push_none but there was no frame",
1427 });
1428 };
1429
1430 if frame.istate.mode != FrameMode::OptionSome {
1432 return Err(ReflectError::OperationFailed {
1433 shape: frame.shape,
1434 operation: "pop_some_push_none called, but frame was not in Option mode",
1435 });
1436 }
1437
1438 if frame.is_fully_initialized() {
1440 return Err(ReflectError::OperationFailed {
1441 shape: frame.shape,
1442 operation: "option frame already initialized, cannot pop_some_push_none",
1443 });
1444 }
1445
1446 frame.dealloc_if_needed();
1447
1448 let _frame = self.frames.pop().expect("frame already checked");
1450
1451 let parent_frame = self
1453 .frames
1454 .last_mut()
1455 .ok_or(ReflectError::OperationFailed {
1456 shape: <()>::SHAPE,
1457 operation: "tried to pop_some_push_none but there was no parent frame",
1458 })?;
1459
1460 unsafe {
1462 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1463 default_fn(parent_frame.data);
1464 } else {
1465 return Err(ReflectError::OperationFailed {
1466 shape: parent_frame.shape,
1467 operation: "option type does not implement Default",
1468 });
1469 }
1470 parent_frame.mark_fully_initialized();
1471 }
1472
1473 let Def::Option(od) = parent_frame.shape.def else {
1474 return Err(ReflectError::OperationFailed {
1475 shape: parent_frame.shape,
1476 operation: "pop_some_push_none and the parent isn't of type Option???",
1477 });
1478 };
1479
1480 let data = parent_frame.data;
1482
1483 let mut frame = Frame {
1484 data,
1485 shape: od.t(),
1486 field_index_in_parent: Some(0),
1487 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1488 };
1489 unsafe {
1490 frame.mark_fully_initialized();
1491 }
1492
1493 self.frames.push(frame);
1494
1495 Ok(self)
1496 }
1497
1498 pub fn push_map_key(mut self) -> Result<Self, ReflectError<'shape>> {
1503 let frame = self.frames.last().unwrap();
1505 let map_shape = frame.shape;
1506
1507 if !matches!(map_shape.def, Def::Map(_)) {
1508 return Err(ReflectError::WasNotA {
1509 expected: "map or hash map",
1510 actual: map_shape,
1511 });
1512 }
1513
1514 if !frame.istate.fields.has(0) {
1516 self = self.begin_map_insert()?;
1517 }
1518
1519 let key_shape = match map_shape.def {
1521 Def::Map(map_def) => map_def.k(),
1522 _ => unreachable!("Already checked map type above"),
1523 };
1524
1525 let key_data = key_shape
1527 .allocate()
1528 .map_err(|_| ReflectError::Unsized { shape: key_shape })?;
1529
1530 let key_frame = Frame {
1532 data: key_data,
1533 shape: key_shape,
1534 field_index_in_parent: None,
1535 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1536 };
1537
1538 trace!(
1539 "[{}] Pushing key of type {} for map {}",
1540 self.frames.len(),
1541 key_shape.green(),
1542 map_shape.blue(),
1543 );
1544
1545 self.frames.push(key_frame);
1546 Ok(self)
1547 }
1548
1549 pub fn push_map_value(mut self) -> Result<Self, ReflectError<'shape>> {
1554 trace!("Wants to push map value. Frames = ");
1555 #[cfg(feature = "log")]
1556 for (i, f) in self.frames.iter().enumerate() {
1557 trace!("Frame {}: {:?}", i, f);
1558 }
1559
1560 if self.frames.len() < 2 {
1562 return Err(ReflectError::OperationFailed {
1563 shape: <()>::SHAPE,
1564 operation: "tried to push map value but there was no key frame",
1565 });
1566 }
1567
1568 let key_frame_index = self.frames.len() - 1;
1570 let key_frame = &self.frames[key_frame_index];
1571
1572 match key_frame.istate.mode {
1574 FrameMode::MapKey => {} _ => {
1576 return Err(ReflectError::OperationFailed {
1577 shape: key_frame.shape,
1578 operation: "current frame is not a map key",
1579 });
1580 }
1581 }
1582
1583 if !key_frame.is_fully_initialized() {
1585 return Err(ReflectError::OperationFailed {
1586 shape: key_frame.shape,
1587 operation: "map key is not fully initialized",
1588 });
1589 }
1590
1591 let map_frame_index = self.frames.len() - 2;
1593 let map_frame = &self.frames[map_frame_index];
1594 let map_shape = map_frame.shape;
1595
1596 let Def::Map(map_def) = map_shape.def else {
1597 return Err(ReflectError::WasNotA {
1598 expected: "map",
1599 actual: map_frame.shape,
1600 });
1601 };
1602
1603 let value_shape = map_def.v();
1604
1605 let value_data = value_shape
1607 .allocate()
1608 .map_err(|_| ReflectError::Unsized { shape: value_shape })?;
1609
1610 let value_frame = Frame {
1612 data: value_data,
1613 shape: value_shape,
1614 field_index_in_parent: None,
1615 istate: IState::new(
1616 self.frames.len(),
1617 FrameMode::MapValue {
1618 index: key_frame_index,
1619 },
1620 FrameFlags::ALLOCATED,
1621 ),
1622 };
1623
1624 trace!(
1625 "[{}] Pushing value of type {} for map {} with key type {}",
1626 self.frames.len(),
1627 value_shape.green(),
1628 map_shape.blue(),
1629 key_frame.shape.yellow(),
1630 );
1631
1632 self.frames.push(value_frame);
1633 Ok(self)
1634 }
1635
1636 pub(crate) fn evict_tree(&mut self, frame: Frame<'shape>) -> Frame<'shape> {
1640 match frame.shape.ty {
1641 Type::User(UserType::Struct(sd)) => {
1642 for f in sd.fields {
1643 let id = ValueId {
1644 shape: f.shape(),
1645 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1646 };
1647 if let Some(istate) = self.istates.remove(&id) {
1648 let frame = Frame::recompose(id, istate);
1649 self.evict_tree(frame);
1650 } else {
1651 trace!("No istate found for field {}", f.name);
1652 }
1653 }
1654 }
1655 Type::User(UserType::Enum(_ed)) => {
1656 if let Some(variant) = &frame.istate.variant {
1658 trace!(
1659 "Evicting enum {} variant '{}' fields",
1660 frame.shape.blue(),
1661 variant.name.yellow()
1662 );
1663 for field in variant.data.fields {
1665 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1667 let field_shape = field.shape();
1668 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1669
1670 if let Some(field_istate) = self.istates.remove(&field_id) {
1672 trace!(
1673 "Evicting field '{}' (shape {}) of enum variant '{}'",
1674 field.name.bright_blue(),
1675 field_shape.green(),
1676 variant.name.yellow()
1677 );
1678 let field_frame = Frame::recompose(field_id, field_istate);
1680 self.evict_tree(field_frame);
1682 } else {
1683 trace!(
1684 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1685 field.name.red(),
1686 field_shape.red(),
1687 variant.name.yellow()
1688 );
1689 }
1690 }
1691 } else {
1692 trace!(
1694 "Enum {} has no variant selected, no fields to evict.",
1695 frame.shape.blue()
1696 );
1697 }
1698 }
1699 _ => {}
1700 }
1701 frame
1702 }
1703
1704 #[allow(rustdoc::broken_intra_doc_links)]
1705 pub fn path(&self) -> String {
1708 let mut path = String::from("$");
1709
1710 for (i, frame) in self.frames.iter().enumerate() {
1711 if i == 0 {
1713 continue;
1714 }
1715
1716 match frame.istate.mode {
1717 FrameMode::ListElement => {
1718 if let Some(index) = frame.istate.list_index {
1720 path.push_str(&format!("[{}]", index));
1721 } else {
1722 path.push_str("[?]");
1723 }
1724 }
1725 FrameMode::MapKey => {
1726 path.push_str(".key");
1727 }
1728 FrameMode::MapValue { index: _ } => {
1729 path.push_str(".value");
1730 }
1731 FrameMode::OptionSome => {
1732 path.push_str(".some");
1733 }
1734 FrameMode::OptionNone => {
1735 path.push_str(".none");
1736 }
1737 FrameMode::SmartPointee => {
1738 path.push_str(".*");
1739 }
1740 FrameMode::Root => {
1741 }
1743 FrameMode::Field => {
1744 if let Some(index) = frame.field_index_in_parent {
1746 if let Some(parent) = self.frames.get(i - 1) {
1748 if let Type::User(UserType::Struct(sd)) = parent.shape.ty {
1749 if index < sd.fields.len() {
1750 let field_name = sd.fields[index].name;
1751 path.push('.');
1752 path.push_str(field_name);
1753 }
1754 } else if let Type::User(UserType::Enum(_)) = parent.shape.ty {
1755 if let Some(variant) = &parent.istate.variant {
1756 if index < variant.data.fields.len() {
1757 let field_name = variant.data.fields[index].name;
1758 path.push('.');
1759 path.push_str(field_name);
1760 }
1761 }
1762 }
1763 }
1764 }
1765 }
1766 }
1767 }
1768
1769 path
1770 }
1771
1772 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError<'shape>> {
1774 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
1775 shape: <()>::SHAPE,
1776 operation: "tried to check if field is set, but there was no frame",
1777 })?;
1778
1779 match frame.shape.ty {
1780 Type::User(UserType::Struct(ref sd)) => {
1781 if index >= sd.fields.len() {
1782 return Err(ReflectError::FieldError {
1783 shape: frame.shape,
1784 field_error: FieldError::NoSuchField,
1785 });
1786 }
1787 Ok(frame.istate.fields.has(index))
1788 }
1789 Type::User(UserType::Enum(_)) => {
1790 let variant = frame.istate.variant.as_ref().ok_or(
1791 ReflectError::OperationFailed {
1792 shape: frame.shape,
1793 operation: "tried to check if field is set, but no variant was selected",
1794 },
1795 )?;
1796 if index >= variant.data.fields.len() {
1797 return Err(ReflectError::FieldError {
1798 shape: frame.shape,
1799 field_error: FieldError::NoSuchField,
1800 });
1801 }
1802 Ok(frame.istate.fields.has(index))
1803 }
1804 _ => Err(ReflectError::WasNotA {
1805 expected: "struct or enum",
1806 actual: frame.shape,
1807 }),
1808 }
1809 }
1810}