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}
132
133pub struct Wip<'facet, 'shape> {
140 frames: alloc::vec::Vec<Frame<'shape>>,
142
143 istates: FlatMap<ValueId<'shape>, IState<'shape>>,
145
146 invariant: PhantomData<fn(&'facet ()) -> &'facet ()>,
147}
148
149impl<'facet, 'shape> Wip<'facet, 'shape> {
150 pub fn put_peek(
152 self,
153 peek: crate::Peek<'_, 'facet, 'shape>,
154 ) -> Result<Wip<'facet, 'shape>, ReflectError<'shape>> {
155 self.put_shape(peek.data, peek.shape)
156 }
157
158 pub fn frames_count(&self) -> usize {
160 self.frames.len()
161 }
162
163 pub fn alloc_shape(shape: &'shape Shape<'shape>) -> Result<Self, ReflectError<'shape>> {
165 let data = shape
166 .allocate()
167 .map_err(|_| ReflectError::Unsized { shape })?;
168 Ok(Self {
169 frames: alloc::vec![Frame {
170 data,
171 shape,
172 field_index_in_parent: None,
173 istate: IState::new(0, FrameMode::Root, FrameFlags::ALLOCATED),
174 }],
175 istates: Default::default(),
176 invariant: PhantomData,
177 })
178 }
179
180 pub fn alloc<S: Facet<'facet>>() -> Result<Self, ReflectError<'shape>> {
182 Self::alloc_shape(S::SHAPE)
183 }
184
185 fn track(&mut self, frame: Frame<'shape>) {
186 if frame.istate.flags.contains(FrameFlags::MOVED) {
192 return;
194 }
195
196 self.istates.insert(frame.id(), frame.istate);
197 }
198
199 unsafe fn mark_moved_out_of(&mut self, frame: &mut Frame<'shape>) {
200 unsafe fn mark_subtree_moved<'facet, 'shape>(
203 wip: &mut Wip<'facet, 'shape>,
204 id: ValueId<'shape>,
205 ) {
206 unsafe {
208 if let Some(mut istate) = wip.istates.remove(&id) {
210 istate.flags.insert(FrameFlags::MOVED);
212
213 match id.shape.ty {
215 Type::User(UserType::Struct(sd)) => {
216 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
217 for field in sd.fields.iter() {
218 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
219 let field_id =
220 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
221 mark_subtree_moved(wip, field_id);
223 }
224 }
225 Type::User(UserType::Enum(_)) => {
226 if let Some(variant) = &istate.variant {
228 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
229 for field in variant.data.fields.iter() {
230 let field_ptr_uninit =
231 container_ptr.field_uninit_at(field.offset);
232 let field_id =
233 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
234 mark_subtree_moved(wip, field_id);
236 }
237 }
238 }
239 _ => {}
243 }
244
245 if istate.flags.contains(FrameFlags::ALLOCATED) {
248 let mut temp_frame = Frame::recompose(id, istate);
250 temp_frame.dealloc_if_needed();
251 }
252 }
253 }
255 }
256
257 unsafe {
260 let frame_id = frame.id();
262
263 let variant_opt = frame.istate.variant;
265
266 frame.istate.flags.insert(FrameFlags::MOVED);
268 ISet::clear(&mut frame.istate.fields);
269
270 match frame.shape.ty {
273 Type::User(UserType::Struct(sd)) => {
274 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
275 for field in sd.fields.iter() {
276 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
277 let field_id = ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
278 mark_subtree_moved(self, field_id);
279 }
280 }
281 Type::User(UserType::Enum(_)) => {
282 if let Some(variant) = &variant_opt {
284 let container_ptr = PtrUninit::new(frame_id.ptr as *mut u8);
285 for field in variant.data.fields.iter() {
286 let field_ptr_uninit = container_ptr.field_uninit_at(field.offset);
287 let field_id =
288 ValueId::new(field.shape(), field_ptr_uninit.as_byte_ptr());
289 mark_subtree_moved(self, field_id);
290 }
291 }
292 }
293 _ => {}
295 }
296
297 frame.istate.variant = None;
299
300 self.istates.remove(&frame_id);
302
303 if frame.istate.flags.contains(FrameFlags::ALLOCATED) {
305 frame.dealloc_if_needed();
306 }
307 }
308 }
309
310 pub fn shape(&self) -> &'shape Shape<'shape> {
312 self.frames.last().expect("must have frames left").shape
313 }
314
315 pub fn innermost_shape(&self) -> &'shape Shape<'shape> {
319 let mut current_shape = self.shape();
320
321 while let Some(inner_fn) = current_shape.inner {
323 current_shape = inner_fn();
324 }
325
326 current_shape
327 }
328
329 pub fn in_option(&self) -> bool {
331 let Some(frame) = self.frames.last() else {
332 return false;
333 };
334 matches!(frame.istate.mode, FrameMode::OptionSome)
335 }
336
337 pub fn mode(&self) -> FrameMode {
339 self.frames.last().unwrap().istate.mode
340 }
341
342 pub fn build(mut self) -> Result<HeapValue<'facet, 'shape>, ReflectError<'shape>> {
344 debug!("[{}] ⚒️ It's BUILD time", self.frames.len());
345
346 if self.frames.is_empty() {
348 panic!("No frames in WIP during build: stack is empty (you popped too much)");
349 }
350 if self.frames.len() != 1 {
351 panic!(
352 "You must pop frames so that only the root frame remains before calling build (frames left: {})",
353 self.frames.len()
354 );
355 }
356
357 let root_frame = &self.frames[0];
359
360 enum FrameRef<'shape> {
361 Root,
362 ById(ValueId<'shape>),
363 }
364 let mut to_check = alloc::vec![FrameRef::Root];
365
366 while let Some(fr) = to_check.pop() {
368 let (id, istate) = match fr {
369 FrameRef::Root => (root_frame.id(), &root_frame.istate),
370 FrameRef::ById(id) => {
371 let istate = self.istates.get(&id).unwrap();
373 (id, istate)
374 }
375 };
376
377 trace!(
378 "Checking shape {} at {:p}, flags={:?}, mode={:?}, fully_initialized={}",
379 id.shape.blue(),
380 id.ptr,
381 istate.flags.bright_magenta(),
382 istate.mode.yellow(),
383 if is_fully_initialized(id.shape, istate) {
384 "✅"
385 } else {
386 "❌"
387 }
388 );
389
390 if istate.flags.contains(FrameFlags::MOVED) {
392 trace!(
393 "{}",
394 "Frame was moved out of, skipping initialization check".yellow()
395 );
396 continue;
397 }
398
399 if let Def::Array(array_def) = id.shape.def {
403 let pushed_count = istate.list_index.unwrap_or(0);
405
406 if pushed_count != array_def.n {
408 return Err(ReflectError::ArrayNotFullyInitialized {
409 shape: id.shape,
410 pushed_count,
411 expected_size: array_def.n,
412 });
413 }
414 }
415 else if !matches!(id.shape.def, Def::Undefined) {
419 if !istate.fields.are_all_set(1) {
420 match istate.mode {
422 FrameMode::OptionNone => {
423 debug!("Found uninitialized value (option none) — {}", id.shape);
425 return Err(ReflectError::UninitializedValue { shape: id.shape });
426 }
427 _ => {
429 debug!(
430 "Found uninitialized value (list/map/option/etc. — {})",
431 id.shape
432 );
433 return Err(ReflectError::UninitializedValue { shape: id.shape });
434 }
435 }
436 }
437 } else {
445 match id.shape.ty {
446 Type::User(UserType::Struct(sd)) => {
447 for i in 0..sd.fields.len() {
449 if !istate.fields.has(i) {
450 let field = &sd.fields[i];
451 trace!("Found uninitialized field: {}", field.name);
452 return Err(ReflectError::UninitializedField {
453 shape: id.shape,
454 field_name: field.name,
455 });
456 }
457 }
458
459 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
460
461 #[allow(clippy::unused_enumerate_index)]
463 for (_i, field) in sd.fields.iter().enumerate() {
464 let field_shape = field.shape();
465 let field_ptr = unsafe { container_ptr.field_init_at(field.offset) };
466 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
467
468 if self.istates.contains_key(&field_id) {
469 debug!(
470 "Queueing struct field check: #{} '{}' of {}: shape={}, ptr={:p}",
471 _i.to_string().bright_cyan(),
472 field.name.bright_blue(),
473 id.shape.blue(),
474 field_shape.green(),
475 field_ptr.as_byte_ptr()
476 );
477 to_check.push(FrameRef::ById(field_id));
478 }
479 }
480 }
481 Type::User(UserType::Enum(_ed)) => {
482 if let Some(variant) = &istate.variant {
483 for (i, field) in variant.data.fields.iter().enumerate() {
485 if !istate.fields.has(i) {
486 trace!("Found uninitialized field: {}", field.name);
487 return Err(ReflectError::UninitializedEnumField {
488 shape: id.shape,
489 variant_name: variant.name,
490 field_name: field.name,
491 });
492 }
493 }
494
495 #[allow(clippy::unused_enumerate_index)]
497 for (_i, field) in variant.data.fields.iter().enumerate() {
498 let field_shape = field.shape();
499 let container_ptr = PtrUninit::new(id.ptr as *mut u8);
500 let field_ptr =
502 unsafe { container_ptr.field_init_at(field.offset) };
503 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
504
505 if self.istates.contains_key(&field_id) {
506 debug!(
507 "Queueing enum field check: #{} '{}' of variant '{}' of {}: shape={}, ptr={:p}",
508 _i.to_string().bright_cyan(),
509 field.name.bright_blue(),
510 variant.name.yellow(),
511 id.shape.blue(),
512 field_shape.green(),
513 field_ptr.as_byte_ptr()
514 );
515 to_check.push(FrameRef::ById(field_id));
516 }
517 }
518 } else {
519 debug!("Found no variant selected for enum");
521 return Err(ReflectError::NoVariantSelected { shape: id.shape });
522 }
523 }
524 _ => {
526 if !istate.fields.are_all_set(1) {
528 debug!("Found uninitialized value (other)");
529 return Err(ReflectError::UninitializedValue { shape: id.shape });
530 }
531 }
532 }
533 }
534 }
535
536 debug!("All reachable frames checked and initialized.");
538
539 let root_shape = root_frame.shape;
542 let root_data = unsafe { root_frame.data.assume_init() };
543 if let Some(invariant_fn) = root_shape.vtable.invariants {
544 debug!(
545 "Checking invariants for root shape {} at {:p}",
546 root_shape.green(),
547 root_data.as_byte_ptr()
548 );
549 if !unsafe { invariant_fn(PtrConst::new(root_data.as_byte_ptr())) } {
550 return Err(ReflectError::InvariantViolation {
551 invariant: "Custom validation function returned false",
552 });
553 }
554 } else {
555 debug!(
556 "No invariants to check for root shape {}",
557 root_shape.blue()
558 );
559 }
560
561 {
563 FlatMap::clear(&mut self.istates);
564 self.frames.clear();
565 }
566
567 let guard = Guard {
569 ptr: root_data.as_mut_byte_ptr(),
570 layout: match root_shape.layout {
571 facet_core::ShapeLayout::Sized(layout) => layout,
572 facet_core::ShapeLayout::Unsized => panic!("Unsized layout not supported"),
573 },
574 };
575
576 Ok(HeapValue {
577 guard: Some(guard),
578 shape: root_shape,
579 phantom: PhantomData,
580 })
581 }
582
583 pub fn field(mut self, index: usize) -> Result<Self, ReflectError<'shape>> {
595 let frame = self.frames.last_mut().unwrap();
596 let shape = frame.shape;
597
598 let (field, field_offset) = match shape.ty {
599 Type::User(UserType::Struct(def)) => {
600 if index >= def.fields.len() {
601 return Err(ReflectError::FieldError {
602 shape,
603 field_error: FieldError::NoSuchField,
604 });
605 }
606 let field = &def.fields[index];
607 (field, field.offset)
608 }
609 Type::User(UserType::Enum(_)) => {
610 let Some(variant) = frame.istate.variant.as_ref() else {
611 return Err(ReflectError::OperationFailed {
612 shape,
613 operation: "tried to access a field but no variant was selected",
614 });
615 };
616
617 if index >= variant.data.fields.len() {
618 return Err(ReflectError::FieldError {
619 shape,
620 field_error: FieldError::NoSuchField,
621 });
622 }
623
624 let field = &variant.data.fields[index];
625 (field, field.offset)
626 }
627 _ => {
628 return Err(ReflectError::WasNotA {
629 expected: "struct or enum",
630 actual: shape,
631 });
632 }
633 };
634
635 let field_data = unsafe { frame.data.field_uninit_at(field_offset) };
636
637 let mut frame = Frame {
638 data: field_data,
639 shape: field.shape(),
640 field_index_in_parent: Some(index),
641 istate: IState::new(self.frames.len(), FrameMode::Field, FrameFlags::EMPTY),
643 };
644 debug!(
645 "[{}] Selecting field {} ({}#{}) of {}",
646 self.frames.len(),
647 field.name.blue(),
648 field.shape().green(),
649 index.yellow(),
650 shape.blue(),
651 );
652 if let Some(iset) = self.istates.remove(&frame.id()) {
653 trace!(
654 "[{}] Restoring saved state for {} (istate.mode = {:?}, istate.fields = {:?}, istate.flags = {:?}, istate.depth = {:?})",
655 self.frames.len(),
656 frame.id().shape.blue(),
657 iset.mode,
658 iset.fields,
659 iset.flags,
660 iset.depth
661 );
662 frame.istate = iset;
663 } else {
664 trace!(
665 "[{}] no saved state for field {} ({}#{}) of {}",
666 self.frames.len(),
667 field.name.blue(),
668 field.shape().green(),
669 index.yellow(),
670 shape.blue(),
671 );
672 }
673 self.frames.push(frame);
674 Ok(self)
675 }
676
677 pub fn field_index(&self, name: &str) -> Option<usize> {
689 fn find_field_index(fields: &[facet_core::Field], name: &str) -> Option<usize> {
690 fields.iter().position(|f| f.name == name)
691 }
692
693 let frame = self.frames.last()?;
694 match frame.shape.ty {
695 Type::User(UserType::Struct(def)) => find_field_index(def.fields, name),
696 Type::User(UserType::Enum(_)) => {
697 let variant = frame.istate.variant.as_ref()?;
698 find_field_index(variant.data.fields, name)
699 }
700 _ => None,
701 }
702 }
703
704 pub fn field_named(self, name: &str) -> Result<Self, ReflectError<'shape>> {
716 let frame = self.frames.last().unwrap();
717 let shape = frame.shape;
718
719 if let Type::User(UserType::Enum(_)) = shape.ty {
721 if frame.istate.variant.is_none() {
722 return Err(ReflectError::OperationFailed {
723 shape,
724 operation: "tried to access a field by name but no variant was selected",
725 });
726 }
727 }
728
729 let index = self.field_index(name).ok_or(ReflectError::FieldError {
730 shape,
731 field_error: FieldError::NoSuchField,
732 })?;
733
734 self.field(index)
735 }
736
737 pub fn put<T: Facet<'facet>>(self, t: T) -> Result<Wip<'facet, 'shape>, ReflectError<'shape>> {
748 let shape = T::SHAPE;
749 let ptr_const = PtrConst::new(&t as *const T as *const u8);
750 let res = self.put_shape(ptr_const, shape);
751 core::mem::forget(t); res
753 }
754
755 pub fn try_put<T: Facet<'facet>>(
766 self,
767 t: T,
768 ) -> Result<Wip<'facet, 'shape>, ReflectError<'shape>> {
769 let shape = T::SHAPE;
770 let ptr_const = PtrConst::new(&t as *const T as *const u8);
771 let res = self.put_shape(ptr_const, shape);
772 core::mem::forget(t); res
774 }
775
776 pub fn parse<'ínput>(mut self, s: &'ínput str) -> Result<Self, ReflectError<'shape>> {
778 let Some(frame) = self.frames.last_mut() else {
779 return Err(ReflectError::OperationFailed {
780 shape: <()>::SHAPE,
781 operation: "tried to parse value but there was no frame",
782 });
783 };
784
785 let shape = frame.shape;
786 let index = frame.field_index_in_parent;
787
788 let Some(parse_fn) = frame.shape.vtable.parse else {
789 return Err(ReflectError::OperationFailed {
790 shape: frame.shape,
791 operation: "type does not implement Parse",
792 });
793 };
794 match unsafe { (parse_fn)(s, frame.data) } {
795 Ok(_res) => {
796 unsafe {
797 frame.mark_fully_initialized();
798 }
799
800 self.mark_field_as_initialized(shape, index)?;
802
803 Ok(self)
804 }
805 Err(_) => Err(ReflectError::OperationFailed {
806 shape,
807 operation: "parsing",
808 }),
809 }
810 }
811
812 pub fn put_from_fn(
814 mut self,
815 default_in_place: DefaultInPlaceFn,
816 ) -> Result<Self, ReflectError<'shape>> {
817 let Some(frame) = self.frames.last_mut() else {
818 return Err(ReflectError::OperationFailed {
819 shape: <()>::SHAPE,
820 operation: "tried to put value from fn but there was no frame",
821 });
822 };
823
824 if let Def::Array(array_def) = frame.shape.def {
827 trace!(
828 "[{}] Setting array as default-initialized with {} elements",
829 frame.istate.depth, array_def.n
830 );
831 frame.istate.list_index = Some(array_def.n);
833 }
834
835 unsafe {
836 default_in_place(frame.data);
837 trace!("Marking frame as fully initialized...");
838 frame.mark_fully_initialized();
839 trace!("Marking frame as fully initialized... done!");
840 }
841
842 let shape = frame.shape;
843 let index = frame.field_index_in_parent;
844
845 self.mark_field_as_initialized(shape, index)?;
847
848 Ok(self)
849 }
850
851 pub fn put_default(self) -> Result<Self, ReflectError<'shape>> {
853 let Some(frame) = self.frames.last() else {
854 return Err(ReflectError::OperationFailed {
855 shape: <()>::SHAPE,
856 operation: "tried to put default value but there was no frame",
857 });
858 };
859
860 let vtable = frame.shape.vtable;
861 let Some(default_in_place) = vtable.default_in_place else {
862 return Err(ReflectError::OperationFailed {
863 shape: frame.shape,
864 operation: "type does not implement Default",
865 });
866 };
867
868 self.put_from_fn(default_in_place)
869 }
870
871 fn mark_field_as_initialized(
873 &mut self,
874 shape: &'shape Shape<'shape>,
875 index: Option<usize>,
876 ) -> Result<(), ReflectError<'shape>> {
877 if let Some(index) = index {
878 let parent_index = self.frames.len().saturating_sub(2);
879 #[cfg(feature = "log")]
880 let num_frames = self.frames.len();
881 let Some(parent) = self.frames.get_mut(parent_index) else {
882 return Err(ReflectError::OperationFailed {
883 shape,
884 operation: "was supposed to mark a field as initialized, but there was no parent frame",
885 });
886 };
887 #[cfg(feature = "log")]
888 let parent_shape = parent.shape;
889 trace!(
890 "[{}] {}.{} initialized with {}",
891 num_frames,
892 parent_shape.blue(),
893 index.yellow(),
894 shape.green()
895 );
896
897 if matches!(parent.shape.ty, Type::User(UserType::Enum(_)))
898 && parent.istate.variant.is_none()
899 {
900 return Err(ReflectError::OperationFailed {
901 shape,
902 operation: "was supposed to mark a field as initialized, but the parent frame was an enum and didn't have a variant chosen",
903 });
904 }
905
906 if parent.istate.fields.has(index) {
907 return Err(ReflectError::OperationFailed {
908 shape,
909 operation: "was supposed to mark a field as initialized, but the parent frame already had it marked as initialized",
910 });
911 }
912
913 parent.istate.fields.set(index);
914 }
915 Ok(())
916 }
917
918 pub fn element_shape(&self) -> Result<&'shape Shape<'shape>, ReflectError<'shape>> {
920 let frame = self.frames.last().unwrap();
921 let shape = frame.shape;
922
923 match shape.def {
924 Def::List(list_def) => Ok(list_def.t()),
925 _ => Err(ReflectError::WasNotA {
926 expected: "list or array",
927 actual: shape,
928 }),
929 }
930 }
931
932 pub fn key_shape(&self) -> Result<&'shape Shape<'shape>, ReflectError<'shape>> {
934 let frame = self.frames.last().unwrap();
935 let shape = frame.shape;
936
937 match shape.def {
938 Def::Map(map_def) => Ok(map_def.k()),
939 _ => Err(ReflectError::WasNotA {
940 expected: "map",
941 actual: shape,
942 }),
943 }
944 }
945
946 pub fn put_empty_list(mut self) -> Result<Self, ReflectError<'shape>> {
948 let Some(frame) = self.frames.last_mut() else {
949 return Err(ReflectError::OperationFailed {
950 shape: <()>::SHAPE,
951 operation: "tried to create empty list but there was no frame",
952 });
953 };
954
955 if !matches!(frame.shape.def, Def::List(_)) {
956 return Err(ReflectError::WasNotA {
957 expected: "list or array",
958 actual: frame.shape,
959 });
960 }
961
962 let vtable = frame.shape.vtable;
963
964 let Some(default_in_place) = vtable.default_in_place else {
966 return Err(ReflectError::OperationFailed {
967 shape: frame.shape,
968 operation: "list type does not implement Default",
969 });
970 };
971
972 unsafe {
973 default_in_place(frame.data);
974 frame.mark_fully_initialized();
975 }
976
977 let shape = frame.shape;
978 let index = frame.field_index_in_parent;
979
980 self.mark_field_as_initialized(shape, index)?;
982
983 Ok(self)
984 }
985
986 pub fn put_empty_map(mut self) -> Result<Self, ReflectError<'shape>> {
988 let Some(frame) = self.frames.last_mut() else {
989 return Err(ReflectError::OperationFailed {
990 shape: <()>::SHAPE,
991 operation: "tried to create empty map but there was no frame",
992 });
993 };
994
995 if !matches!(frame.shape.def, Def::Map(_)) {
996 return Err(ReflectError::WasNotA {
997 expected: "map or hash map",
998 actual: frame.shape,
999 });
1000 }
1001
1002 let vtable = frame.shape.vtable;
1003
1004 let Some(default_in_place) = vtable.default_in_place else {
1006 return Err(ReflectError::OperationFailed {
1007 shape: frame.shape,
1008 operation: "map type does not implement Default",
1009 });
1010 };
1011
1012 unsafe {
1013 default_in_place(frame.data);
1014 frame.mark_fully_initialized();
1015 }
1016
1017 if let Some(index) = frame.field_index_in_parent {
1019 let parent_index = self.frames.len().saturating_sub(2);
1020 if let Some(parent) = self.frames.get_mut(parent_index) {
1021 parent.istate.fields.set(index);
1022 }
1023 }
1024
1025 Ok(self)
1026 }
1027
1028 pub fn begin_pushback(mut self) -> Result<Self, ReflectError<'shape>> {
1033 let Some(frame) = self.frames.last_mut() else {
1034 return Err(ReflectError::OperationFailed {
1035 shape: <()>::SHAPE,
1036 operation: "tried to begin pushback but there was no frame",
1037 });
1038 };
1039
1040 let is_list = matches!(frame.shape.def, Def::List(_));
1041 let is_array = matches!(frame.shape.def, Def::Array(_));
1042 let is_tuple_struct_or_variant = match (frame.shape.ty, frame.shape.def) {
1043 (_, Def::Scalar(sd)) => matches!(sd.affinity, ScalarAffinity::Empty(_)),
1044 (Type::Sequence(_), _) => true,
1045 (Type::User(UserType::Struct(sd)), _) => sd.kind == facet_core::StructKind::Tuple,
1046 (Type::User(UserType::Enum(_)), _) => {
1047 if let Some(variant) = &frame.istate.variant {
1049 variant.data.kind == facet_core::StructKind::Tuple
1050 } else {
1051 false }
1060 }
1061 _ => false,
1062 };
1063
1064 if !is_list && !is_array && !is_tuple_struct_or_variant {
1065 return Err(ReflectError::WasNotA {
1066 expected: "list, array, or tuple-like struct/enum variant",
1067 actual: frame.shape,
1068 });
1069 }
1070
1071 if is_list {
1073 let vtable = frame.shape.vtable;
1074 if !frame.istate.fields.has(0) {
1076 let Some(default_in_place) = vtable.default_in_place else {
1077 return Err(ReflectError::OperationFailed {
1078 shape: frame.shape,
1079 operation: "list type does not implement Default, cannot begin pushback",
1080 });
1081 };
1082
1083 unsafe {
1084 default_in_place(frame.data);
1085 frame.istate.fields.set(0);
1087 }
1088 }
1089 }
1090 else if is_array {
1092 frame.istate.list_index = Some(0);
1094 }
1095 Ok(self)
1098 }
1099
1100 pub fn begin_map_insert(mut self) -> Result<Self, ReflectError<'shape>> {
1102 let Some(frame) = self.frames.last_mut() else {
1103 return Err(ReflectError::OperationFailed {
1104 shape: <()>::SHAPE,
1105 operation: "tried to begin map insertion but there was no frame",
1106 });
1107 };
1108
1109 if !matches!(frame.shape.def, Def::Map(_)) {
1110 return Err(ReflectError::WasNotA {
1111 expected: "map or hash map",
1112 actual: frame.shape,
1113 });
1114 }
1115
1116 let vtable = frame.shape.vtable;
1117
1118 if !frame.istate.fields.has(0) {
1120 let Some(default_in_place) = vtable.default_in_place else {
1121 return Err(ReflectError::OperationFailed {
1122 shape: frame.shape,
1123 operation: "map type does not implement Default",
1124 });
1125 };
1126
1127 unsafe {
1128 default_in_place(frame.data);
1129 frame.istate.fields.set(0);
1130 }
1131 }
1132
1133 Ok(self)
1134 }
1135
1136 pub fn push(mut self) -> Result<Self, ReflectError<'shape>> {
1141 let frame_len = self.frames.len();
1143 let frame = self
1144 .frames
1145 .last_mut()
1146 .ok_or(ReflectError::OperationFailed {
1147 shape: <()>::SHAPE,
1148 operation: "tried to push but there was no frame",
1149 })?;
1150 let seq_shape = frame.shape;
1151
1152 let (element_shape, context_str): (&'shape Shape<'shape>, &'shape str) =
1154 match (seq_shape.ty, seq_shape.def) {
1155 (_, Def::List(list_def)) => {
1156 if !frame.istate.fields.has(0) {
1158 return self.begin_pushback()?.push();
1161 }
1162 let shape = list_def.t();
1164 (shape, "list")
1165 }
1166 (_, Def::Array(array_def)) => {
1167 let index = frame.istate.list_index.unwrap_or(0);
1169
1170 if index >= array_def.n {
1172 return Err(ReflectError::ArrayIndexOutOfBounds {
1173 shape: seq_shape,
1174 index,
1175 size: array_def.n,
1176 });
1177 }
1178
1179 frame.istate.list_index = Some(index + 1);
1181
1182 let element_shape = array_def.t;
1184 (element_shape, "array")
1185 }
1186 (Type::Sequence(SequenceType::Tuple(tt)), _) => {
1187 let field_index = {
1189 let next_idx = frame.istate.list_index.unwrap_or(0);
1191 frame.istate.list_index = Some(next_idx + 1);
1192 next_idx
1193 };
1194 if field_index >= tt.fields.len() {
1196 return Err(ReflectError::FieldError {
1197 shape: seq_shape,
1198 field_error: FieldError::NoSuchField,
1199 });
1200 }
1201 (tt.fields[field_index].shape(), "tuple")
1203 }
1204 (Type::User(UserType::Struct(sd)), _)
1205 if sd.kind == facet_core::StructKind::Tuple =>
1206 {
1207 let field_index = {
1209 let next_idx = frame.istate.list_index.unwrap_or(0);
1211 frame.istate.list_index = Some(next_idx + 1);
1212 next_idx
1213 };
1214 if field_index >= sd.fields.len() {
1216 return Err(ReflectError::FieldError {
1217 shape: seq_shape,
1218 field_error: FieldError::NoSuchField, });
1220 }
1221 (sd.fields[field_index].shape(), "tuple struct")
1223 }
1224
1225 (Type::User(UserType::Enum(_)), _) => {
1226 let variant =
1228 frame
1229 .istate
1230 .variant
1231 .as_ref()
1232 .ok_or(ReflectError::OperationFailed {
1233 shape: seq_shape,
1234 operation: "tried to push onto enum but no variant was selected",
1235 })?;
1236 if variant.data.kind != facet_core::StructKind::Tuple {
1238 return Err(ReflectError::WasNotA {
1239 expected: "tuple-like enum variant",
1240 actual: seq_shape, });
1242 }
1243 let field_index = {
1245 let next_idx = frame.istate.list_index.unwrap_or(0);
1247 frame.istate.list_index = Some(next_idx + 1);
1248 next_idx
1249 };
1250 if field_index >= variant.data.fields.len() {
1252 return Err(ReflectError::FieldError {
1253 shape: seq_shape, field_error: FieldError::NoSuchField,
1255 });
1256 }
1257 (
1259 variant.data.fields[field_index].shape(),
1260 "tuple enum variant",
1261 )
1262 }
1263 (_, Def::Scalar(sd)) if matches!(sd.affinity, ScalarAffinity::Empty(_)) => {
1264 return Err(ReflectError::OperationFailed {
1266 shape: seq_shape,
1267 operation: "cannot push elements to unit type ()",
1268 });
1269 }
1270 _ => {
1271 return Err(ReflectError::WasNotA {
1273 expected: "list, array, tuple, tuple struct, or tuple enum variant",
1274 actual: seq_shape,
1275 });
1276 }
1277 };
1278
1279 let element_data = element_shape
1281 .allocate()
1282 .map_err(|_| ReflectError::Unsized {
1283 shape: element_shape,
1284 })?;
1285
1286 let element_frame = Frame {
1288 data: element_data,
1289 shape: element_shape,
1290 field_index_in_parent: None, istate: IState::new(
1292 frame_len, FrameMode::ListElement, FrameFlags::ALLOCATED,
1295 ),
1296 };
1297
1298 trace!(
1299 "[{}] Pushing element of type {} to {} {}",
1300 frame_len,
1301 element_shape.green(),
1302 context_str, seq_shape.blue(),
1304 );
1305 let _ = context_str;
1306
1307 self.frames.push(element_frame);
1308 Ok(self)
1309 }
1310
1311 pub fn push_some(mut self) -> Result<Self, ReflectError<'shape>> {
1313 let frame = self.frames.last().unwrap();
1315 let option_shape = frame.shape;
1316
1317 let Def::Option(option_def) = option_shape.def else {
1319 return Err(ReflectError::WasNotA {
1320 expected: "option",
1321 actual: option_shape,
1322 });
1323 };
1324
1325 let inner_shape = option_def.t();
1327
1328 let inner_data = inner_shape
1330 .allocate()
1331 .map_err(|_| ReflectError::Unsized { shape: inner_shape })?;
1332
1333 let inner_frame = Frame {
1335 data: inner_data,
1336 shape: inner_shape,
1337 field_index_in_parent: None,
1339 istate: IState::new(
1340 self.frames.len(),
1341 FrameMode::OptionSome,
1342 FrameFlags::ALLOCATED,
1344 ),
1345 };
1346
1347 trace!(
1348 "[{}] Pushing option frame for {}",
1349 self.frames.len(),
1350 option_shape.blue(),
1351 );
1352
1353 self.frames.push(inner_frame);
1354 Ok(self)
1355 }
1356
1357 pub fn pop_some_push_none(mut self) -> Result<Self, ReflectError<'shape>> {
1367 let Some(frame) = self.frames.last_mut() else {
1369 return Err(ReflectError::OperationFailed {
1370 shape: <()>::SHAPE,
1371 operation: "tried to pop_some_push_none but there was no frame",
1372 });
1373 };
1374
1375 if frame.istate.mode != FrameMode::OptionSome {
1377 return Err(ReflectError::OperationFailed {
1378 shape: frame.shape,
1379 operation: "pop_some_push_none called, but frame was not in Option mode",
1380 });
1381 }
1382
1383 if frame.is_fully_initialized() {
1385 return Err(ReflectError::OperationFailed {
1386 shape: frame.shape,
1387 operation: "option frame already initialized, cannot pop_some_push_none",
1388 });
1389 }
1390
1391 frame.dealloc_if_needed();
1392
1393 let _frame = self.frames.pop().expect("frame already checked");
1395
1396 let parent_frame = self
1398 .frames
1399 .last_mut()
1400 .ok_or(ReflectError::OperationFailed {
1401 shape: <()>::SHAPE,
1402 operation: "tried to pop_some_push_none but there was no parent frame",
1403 })?;
1404
1405 unsafe {
1407 if let Some(default_fn) = parent_frame.shape.vtable.default_in_place {
1408 default_fn(parent_frame.data);
1409 } else {
1410 return Err(ReflectError::OperationFailed {
1411 shape: parent_frame.shape,
1412 operation: "option type does not implement Default",
1413 });
1414 }
1415 parent_frame.mark_fully_initialized();
1416 }
1417
1418 let Def::Option(od) = parent_frame.shape.def else {
1419 return Err(ReflectError::OperationFailed {
1420 shape: parent_frame.shape,
1421 operation: "pop_some_push_none and the parent isn't of type Option???",
1422 });
1423 };
1424
1425 let data = parent_frame.data;
1427
1428 let mut frame = Frame {
1429 data,
1430 shape: od.t(),
1431 field_index_in_parent: Some(0),
1432 istate: IState::new(self.frames.len(), FrameMode::OptionNone, FrameFlags::EMPTY),
1433 };
1434 unsafe {
1435 frame.mark_fully_initialized();
1436 }
1437
1438 self.frames.push(frame);
1439
1440 Ok(self)
1441 }
1442
1443 pub fn push_map_key(mut self) -> Result<Self, ReflectError<'shape>> {
1448 let frame = self.frames.last().unwrap();
1450 let map_shape = frame.shape;
1451
1452 if !matches!(map_shape.def, Def::Map(_)) {
1453 return Err(ReflectError::WasNotA {
1454 expected: "map or hash map",
1455 actual: map_shape,
1456 });
1457 }
1458
1459 if !frame.istate.fields.has(0) {
1461 self = self.begin_map_insert()?;
1462 }
1463
1464 let key_shape = match map_shape.def {
1466 Def::Map(map_def) => map_def.k(),
1467 _ => unreachable!("Already checked map type above"),
1468 };
1469
1470 let key_data = key_shape
1472 .allocate()
1473 .map_err(|_| ReflectError::Unsized { shape: key_shape })?;
1474
1475 let key_frame = Frame {
1477 data: key_data,
1478 shape: key_shape,
1479 field_index_in_parent: None,
1480 istate: IState::new(self.frames.len(), FrameMode::MapKey, FrameFlags::ALLOCATED),
1481 };
1482
1483 trace!(
1484 "[{}] Pushing key of type {} for map {}",
1485 self.frames.len(),
1486 key_shape.green(),
1487 map_shape.blue(),
1488 );
1489
1490 self.frames.push(key_frame);
1491 Ok(self)
1492 }
1493
1494 pub fn push_map_value(mut self) -> Result<Self, ReflectError<'shape>> {
1499 trace!("Wants to push map value. Frames = ");
1500 #[cfg(feature = "log")]
1501 for (i, f) in self.frames.iter().enumerate() {
1502 trace!("Frame {}: {:?}", i, f);
1503 }
1504
1505 if self.frames.len() < 2 {
1507 return Err(ReflectError::OperationFailed {
1508 shape: <()>::SHAPE,
1509 operation: "tried to push map value but there was no key frame",
1510 });
1511 }
1512
1513 let key_frame_index = self.frames.len() - 1;
1515 let key_frame = &self.frames[key_frame_index];
1516
1517 match key_frame.istate.mode {
1519 FrameMode::MapKey => {} _ => {
1521 return Err(ReflectError::OperationFailed {
1522 shape: key_frame.shape,
1523 operation: "current frame is not a map key",
1524 });
1525 }
1526 }
1527
1528 if !key_frame.is_fully_initialized() {
1530 return Err(ReflectError::OperationFailed {
1531 shape: key_frame.shape,
1532 operation: "map key is not fully initialized",
1533 });
1534 }
1535
1536 let map_frame_index = self.frames.len() - 2;
1538 let map_frame = &self.frames[map_frame_index];
1539 let map_shape = map_frame.shape;
1540
1541 let Def::Map(map_def) = map_shape.def else {
1542 return Err(ReflectError::WasNotA {
1543 expected: "map",
1544 actual: map_frame.shape,
1545 });
1546 };
1547
1548 let value_shape = map_def.v();
1549
1550 let value_data = value_shape
1552 .allocate()
1553 .map_err(|_| ReflectError::Unsized { shape: value_shape })?;
1554
1555 let value_frame = Frame {
1557 data: value_data,
1558 shape: value_shape,
1559 field_index_in_parent: None,
1560 istate: IState::new(
1561 self.frames.len(),
1562 FrameMode::MapValue {
1563 index: key_frame_index,
1564 },
1565 FrameFlags::ALLOCATED,
1566 ),
1567 };
1568
1569 trace!(
1570 "[{}] Pushing value of type {} for map {} with key type {}",
1571 self.frames.len(),
1572 value_shape.green(),
1573 map_shape.blue(),
1574 key_frame.shape.yellow(),
1575 );
1576
1577 self.frames.push(value_frame);
1578 Ok(self)
1579 }
1580
1581 pub(crate) fn evict_tree(&mut self, frame: Frame<'shape>) -> Frame<'shape> {
1585 match frame.shape.ty {
1586 Type::User(UserType::Struct(sd)) => {
1587 for f in sd.fields {
1588 let id = ValueId {
1589 shape: f.shape(),
1590 ptr: unsafe { frame.data.field_uninit_at(f.offset) }.as_byte_ptr(),
1591 };
1592 if let Some(istate) = self.istates.remove(&id) {
1593 let frame = Frame::recompose(id, istate);
1594 self.evict_tree(frame);
1595 } else {
1596 trace!("No istate found for field {}", f.name);
1597 }
1598 }
1599 }
1600 Type::User(UserType::Enum(_ed)) => {
1601 if let Some(variant) = &frame.istate.variant {
1603 trace!(
1604 "Evicting enum {} variant '{}' fields",
1605 frame.shape.blue(),
1606 variant.name.yellow()
1607 );
1608 for field in variant.data.fields {
1610 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1612 let field_shape = field.shape();
1613 let field_id = ValueId::new(field_shape, field_ptr.as_byte_ptr());
1614
1615 if let Some(field_istate) = self.istates.remove(&field_id) {
1617 trace!(
1618 "Evicting field '{}' (shape {}) of enum variant '{}'",
1619 field.name.bright_blue(),
1620 field_shape.green(),
1621 variant.name.yellow()
1622 );
1623 let field_frame = Frame::recompose(field_id, field_istate);
1625 self.evict_tree(field_frame);
1627 } else {
1628 trace!(
1629 "Field '{}' (shape {}) of enum variant '{}' not found in istates, skipping eviction",
1630 field.name.red(),
1631 field_shape.red(),
1632 variant.name.yellow()
1633 );
1634 }
1635 }
1636 } else {
1637 trace!(
1639 "Enum {} has no variant selected, no fields to evict.",
1640 frame.shape.blue()
1641 );
1642 }
1643 }
1644 _ => {}
1645 }
1646 frame
1647 }
1648
1649 #[allow(rustdoc::broken_intra_doc_links)]
1650 pub fn path(&self) -> String {
1653 let mut path = String::from("$");
1654
1655 for (i, frame) in self.frames.iter().enumerate() {
1656 if i == 0 {
1658 continue;
1659 }
1660
1661 match frame.istate.mode {
1662 FrameMode::ListElement => {
1663 if let Some(index) = frame.istate.list_index {
1665 path.push_str(&format!("[{}]", index));
1666 } else {
1667 path.push_str("[?]");
1668 }
1669 }
1670 FrameMode::MapKey => {
1671 path.push_str(".key");
1672 }
1673 FrameMode::MapValue { index: _ } => {
1674 path.push_str(".value");
1675 }
1676 FrameMode::OptionSome => {
1677 path.push_str(".some");
1678 }
1679 FrameMode::OptionNone => {
1680 path.push_str(".none");
1681 }
1682 FrameMode::Root => {
1683 }
1685 FrameMode::Field => {
1686 if let Some(index) = frame.field_index_in_parent {
1688 if let Some(parent) = self.frames.get(i - 1) {
1690 if let Type::User(UserType::Struct(sd)) = parent.shape.ty {
1691 if index < sd.fields.len() {
1692 let field_name = sd.fields[index].name;
1693 path.push('.');
1694 path.push_str(field_name);
1695 }
1696 } else if let Type::User(UserType::Enum(_)) = parent.shape.ty {
1697 if let Some(variant) = &parent.istate.variant {
1698 if index < variant.data.fields.len() {
1699 let field_name = variant.data.fields[index].name;
1700 path.push('.');
1701 path.push_str(field_name);
1702 }
1703 }
1704 }
1705 }
1706 }
1707 }
1708 }
1709 }
1710
1711 path
1712 }
1713
1714 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError<'shape>> {
1716 let frame = self.frames.last().ok_or(ReflectError::OperationFailed {
1717 shape: <()>::SHAPE,
1718 operation: "tried to check if field is set, but there was no frame",
1719 })?;
1720
1721 match frame.shape.ty {
1722 Type::User(UserType::Struct(ref sd)) => {
1723 if index >= sd.fields.len() {
1724 return Err(ReflectError::FieldError {
1725 shape: frame.shape,
1726 field_error: FieldError::NoSuchField,
1727 });
1728 }
1729 Ok(frame.istate.fields.has(index))
1730 }
1731 Type::User(UserType::Enum(_)) => {
1732 let variant = frame.istate.variant.as_ref().ok_or(
1733 ReflectError::OperationFailed {
1734 shape: frame.shape,
1735 operation: "tried to check if field is set, but no variant was selected",
1736 },
1737 )?;
1738 if index >= variant.data.fields.len() {
1739 return Err(ReflectError::FieldError {
1740 shape: frame.shape,
1741 field_error: FieldError::NoSuchField,
1742 });
1743 }
1744 Ok(frame.istate.fields.has(index))
1745 }
1746 _ => Err(ReflectError::WasNotA {
1747 expected: "struct or enum",
1748 actual: frame.shape,
1749 }),
1750 }
1751 }
1752}