1use alloc::{
4 boxed::Box,
5 format,
6 string::{String, ToString},
7 vec::Vec,
8};
9
10use core::{marker::PhantomData, mem::ManuallyDrop, ptr::NonNull};
11
12use crate::{
13 Guard, HeapValue, Partial, Peek, ReflectError, TypedPartial,
14 partial::{Frame, FrameOwnership, MapInsertState, PartialState, Tracker, iset::ISet},
15 trace,
16};
17use facet_core::{
18 ArrayType, Characteristic, Def, EnumRepr, EnumType, Facet, Field, FieldAttribute, KnownPointer,
19 PtrConst, PtrMut, PtrUninit, SequenceType, Shape, StructType, Type, UserType, Variant,
20};
21
22impl<'facet> Partial<'facet> {
26 pub fn alloc<T>() -> Result<TypedPartial<'facet, T>, ReflectError>
28 where
29 T: Facet<'facet> + ?Sized,
30 {
31 Ok(TypedPartial {
32 inner: Self::alloc_shape(T::SHAPE)?,
33 phantom: PhantomData,
34 })
35 }
36
37 pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
39 crate::trace!(
40 "alloc_shape({:?}), with layout {:?}",
41 shape,
42 shape.layout.sized_layout()
43 );
44
45 let data = shape.allocate().map_err(|_| ReflectError::Unsized {
46 shape,
47 operation: "alloc_shape",
48 })?;
49
50 let mut frames = Vec::with_capacity(4);
54 frames.push(Frame::new(data, shape, FrameOwnership::Owned));
55
56 Ok(Self {
57 frames,
58 state: PartialState::Active,
59 invariant: PhantomData,
60 })
61 }
62}
63
64impl<'facet> Partial<'facet> {
68 #[inline]
77 pub fn frame_count(&self) -> usize {
78 self.frames.len()
79 }
80
81 #[inline]
83 pub fn shape(&self) -> &'static Shape {
84 self.frames
85 .last()
86 .expect("Partial always has at least one frame")
87 .shape
88 }
89
90 pub fn end(&mut self) -> Result<&mut Self, ReflectError> {
92 crate::trace!("end() called");
93 self.require_active()?;
94
95 if self.frames.len() == 1 {
97 if let Tracker::SmartPointerSlice {
98 vtable,
99 building_item,
100 } = &self.frames[0].tracker
101 {
102 if *building_item {
103 return Err(ReflectError::OperationFailed {
104 shape: self.frames[0].shape,
105 operation: "still building an item, finish it first",
106 });
107 }
108
109 let builder_ptr = unsafe { self.frames[0].data.assume_init() };
111 let arc_ptr = unsafe { (vtable.convert_fn)(builder_ptr) };
112
113 self.frames[0].data = PtrUninit::new(unsafe {
115 NonNull::new_unchecked(arc_ptr.as_byte_ptr() as *mut u8)
116 });
117 self.frames[0].tracker = Tracker::Init;
118 self.frames[0].ownership = FrameOwnership::ManagedElsewhere;
120
121 return Ok(self);
122 }
123 }
124
125 if self.frames.len() <= 1 {
126 return Err(ReflectError::InvariantViolation {
128 invariant: "Partial::end() called with only one frame on the stack",
129 });
130 }
131
132 {
134 let frame = self.frames.last().unwrap();
135 trace!(
136 "end(): Checking full initialization for frame with shape {} and tracker {:?}",
137 frame.shape,
138 frame.tracker.kind()
139 );
140 frame.require_full_initialization()?
141 }
142
143 let mut popped_frame = self.frames.pop().unwrap();
145
146 if popped_frame.using_custom_deserialization {
148 if let Some(deserialize_with) = self
149 .parent_field()
150 .and_then(|field| field.vtable.deserialize_with)
151 {
152 let parent_frame = self.frames.last_mut().unwrap();
153
154 trace!(
155 "Detected custom conversion needed from {} to {}",
156 popped_frame.shape, parent_frame.shape
157 );
158
159 unsafe {
160 let res = {
161 let inner_value_ptr = popped_frame.data.assume_init().as_const();
162 (deserialize_with)(inner_value_ptr, parent_frame.data)
163 };
164 let popped_frame_shape = popped_frame.shape;
165
166 popped_frame.deinit();
168 popped_frame.dealloc();
169 let rptr = res.map_err(|message| ReflectError::CustomDeserializationError {
170 message,
171 src_shape: popped_frame_shape,
172 dst_shape: parent_frame.shape,
173 })?;
174 if rptr.as_uninit() != parent_frame.data {
175 return Err(ReflectError::CustomDeserializationError {
176 message: "deserialize_with did not return the expected pointer".into(),
177 src_shape: popped_frame_shape,
178 dst_shape: parent_frame.shape,
179 });
180 }
181 parent_frame.mark_as_init();
182 }
183 return Ok(self);
184 }
185 }
186
187 let parent_frame = self.frames.last_mut().unwrap();
189
190 trace!(
191 "end(): Popped {} (tracker {:?}), Parent {} (tracker {:?})",
192 popped_frame.shape,
193 popped_frame.tracker.kind(),
194 parent_frame.shape,
195 parent_frame.tracker.kind()
196 );
197
198 let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
203 && parent_frame.shape.inner.is_some()
204 && parent_frame.shape.inner.unwrap() == popped_frame.shape
205 && parent_frame.shape.vtable.try_from.is_some();
206
207 if needs_conversion {
208 trace!(
209 "Detected implicit conversion needed from {} to {}",
210 popped_frame.shape, parent_frame.shape
211 );
212 if let Some(try_from_fn) = parent_frame.shape.vtable.try_from {
214 let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
215 let inner_shape = popped_frame.shape;
216
217 trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
218 let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
219
220 if let Err(e) = result {
221 trace!("Conversion failed: {e:?}");
222
223 if let FrameOwnership::Owned = popped_frame.ownership {
225 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
226 if layout.size() > 0 {
227 trace!(
228 "Deallocating conversion frame memory after failure: size={}, align={}",
229 layout.size(),
230 layout.align()
231 );
232 unsafe {
233 alloc::alloc::dealloc(
234 popped_frame.data.as_mut_byte_ptr(),
235 layout,
236 );
237 }
238 }
239 }
240 }
241
242 return Err(ReflectError::TryFromError {
243 src_shape: inner_shape,
244 dst_shape: parent_frame.shape,
245 inner: e,
246 });
247 }
248
249 trace!("Conversion succeeded, marking parent as initialized");
250 parent_frame.tracker = Tracker::Init;
251
252 if let FrameOwnership::Owned = popped_frame.ownership {
254 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
255 if layout.size() > 0 {
256 trace!(
257 "Deallocating conversion frame memory: size={}, align={}",
258 layout.size(),
259 layout.align()
260 );
261 unsafe {
262 alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
263 }
264 }
265 }
266 }
267
268 return Ok(self);
269 }
270 }
271
272 match &mut parent_frame.tracker {
273 Tracker::Struct {
274 iset,
275 current_child,
276 } => {
277 if let Some(idx) = *current_child {
278 iset.set(idx);
279 *current_child = None;
280 }
281 }
282 Tracker::Array {
283 iset,
284 current_child,
285 } => {
286 if let Some(idx) = *current_child {
287 iset.set(idx);
288 *current_child = None;
289 }
290 }
291 Tracker::SmartPointer { is_initialized } => {
292 if let Def::Pointer(smart_ptr_def) = parent_frame.shape.def {
294 let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn else {
295 return Err(ReflectError::OperationFailed {
296 shape: parent_frame.shape,
297 operation: "SmartPointer missing new_into_fn",
298 });
299 };
300
301 let inner_ptr = PtrMut::new(unsafe {
303 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
304 });
305
306 unsafe {
308 new_into_fn(parent_frame.data, inner_ptr);
309 }
310
311 popped_frame.tracker = Tracker::Uninit;
313
314 popped_frame.dealloc();
316
317 *is_initialized = true;
318 }
319 }
320 Tracker::Enum {
321 data,
322 current_child,
323 ..
324 } => {
325 if let Some(idx) = *current_child {
326 data.set(idx);
327 *current_child = None;
328 }
329 }
330 Tracker::List {
331 is_initialized: true,
332 current_child,
333 } => {
334 if *current_child {
335 if let Def::List(list_def) = parent_frame.shape.def {
337 let Some(push_fn) = list_def.vtable.push else {
338 return Err(ReflectError::OperationFailed {
339 shape: parent_frame.shape,
340 operation: "List missing push function",
341 });
342 };
343
344 let element_ptr = PtrMut::new(unsafe {
346 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
347 });
348
349 unsafe {
351 push_fn(
352 PtrMut::new(NonNull::new_unchecked(
353 parent_frame.data.as_mut_byte_ptr(),
354 )),
355 element_ptr,
356 );
357 }
358
359 popped_frame.tracker = Tracker::Uninit;
361 popped_frame.dealloc();
362
363 *current_child = false;
364 }
365 }
366 }
367 Tracker::Map {
368 is_initialized: true,
369 insert_state,
370 } => {
371 match insert_state {
372 MapInsertState::PushingKey { key_ptr } => {
373 if let Some(key_ptr) = key_ptr {
375 *insert_state = MapInsertState::PushingValue {
377 key_ptr: *key_ptr,
378 value_ptr: None,
379 };
380 }
381 }
382 MapInsertState::PushingValue { key_ptr, value_ptr } => {
383 if let (Some(value_ptr), Def::Map(map_def)) =
385 (value_ptr, parent_frame.shape.def)
386 {
387 let insert_fn = map_def.vtable.insert_fn;
388
389 unsafe {
391 insert_fn(
392 PtrMut::new(NonNull::new_unchecked(
393 parent_frame.data.as_mut_byte_ptr(),
394 )),
395 PtrMut::new(NonNull::new_unchecked(key_ptr.as_mut_byte_ptr())),
396 PtrMut::new(NonNull::new_unchecked(
397 value_ptr.as_mut_byte_ptr(),
398 )),
399 );
400 }
401
402 if let Ok(key_shape) = map_def.k().layout.sized_layout() {
408 if key_shape.size() > 0 {
409 unsafe {
410 alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
411 }
412 }
413 }
414 if let Ok(value_shape) = map_def.v().layout.sized_layout() {
415 if value_shape.size() > 0 {
416 unsafe {
417 alloc::alloc::dealloc(
418 value_ptr.as_mut_byte_ptr(),
419 value_shape,
420 );
421 }
422 }
423 }
424
425 *insert_state = MapInsertState::Idle;
427 }
428 }
429 MapInsertState::Idle => {
430 }
432 }
433 }
434 Tracker::Set {
435 is_initialized: true,
436 current_child,
437 } => {
438 if *current_child {
439 if let Def::Set(set_def) = parent_frame.shape.def {
441 let insert_fn = set_def.vtable.insert_fn;
442
443 let element_ptr = PtrMut::new(unsafe {
445 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
446 });
447
448 unsafe {
450 insert_fn(
451 PtrMut::new(NonNull::new_unchecked(
452 parent_frame.data.as_mut_byte_ptr(),
453 )),
454 element_ptr,
455 );
456 }
457
458 popped_frame.tracker = Tracker::Uninit;
460 popped_frame.dealloc();
461
462 *current_child = false;
463 }
464 }
465 }
466 Tracker::Option { building_inner } => {
467 if *building_inner {
469 if let Def::Option(option_def) = parent_frame.shape.def {
470 let init_some_fn = option_def.vtable.init_some_fn;
472
473 let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
475
476 unsafe {
478 init_some_fn(parent_frame.data, inner_value_ptr);
479 }
480
481 if let FrameOwnership::Owned = popped_frame.ownership {
483 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
484 if layout.size() > 0 {
485 unsafe {
486 alloc::alloc::dealloc(
487 popped_frame.data.as_mut_byte_ptr(),
488 layout,
489 );
490 }
491 }
492 }
493 }
494
495 *building_inner = false;
497 } else {
498 return Err(ReflectError::OperationFailed {
499 shape: parent_frame.shape,
500 operation: "Option frame without Option definition",
501 });
502 }
503 }
504 }
505 Tracker::Uninit | Tracker::Init => {
506 match &parent_frame.shape.def {
509 Def::Pointer(smart_ptr_def) => {
510 let pointee =
511 smart_ptr_def
512 .pointee()
513 .ok_or(ReflectError::InvariantViolation {
514 invariant: "pointer type doesn't have a pointee",
515 })?;
516
517 if !pointee.is_shape(str::SHAPE) {
518 return Err(ReflectError::InvariantViolation {
519 invariant: "only T=str is supported when building SmartPointer<T> and T is unsized",
520 });
521 }
522
523 if !popped_frame.shape.is_shape(String::SHAPE) {
524 return Err(ReflectError::InvariantViolation {
525 invariant: "the popped frame should be String when building a SmartPointer<T>",
526 });
527 }
528
529 popped_frame.require_full_initialization()?;
530
531 use alloc::{rc::Rc, string::String, sync::Arc};
536 let parent_shape = parent_frame.shape;
537
538 let Some(known) = smart_ptr_def.known else {
539 return Err(ReflectError::OperationFailed {
540 shape: parent_shape,
541 operation: "SmartPointerStr for unknown smart pointer kind",
542 });
543 };
544
545 parent_frame.deinit();
546
547 let string_ptr = popped_frame.data.as_mut_byte_ptr() as *mut String;
549 let string_value = unsafe { core::ptr::read(string_ptr) };
550
551 match known {
552 KnownPointer::Box => {
553 let boxed: Box<str> = string_value.into_boxed_str();
554 unsafe {
555 core::ptr::write(
556 parent_frame.data.as_mut_byte_ptr() as *mut Box<str>,
557 boxed,
558 );
559 }
560 }
561 KnownPointer::Arc => {
562 let arc: Arc<str> = Arc::from(string_value.into_boxed_str());
563 unsafe {
564 core::ptr::write(
565 parent_frame.data.as_mut_byte_ptr() as *mut Arc<str>,
566 arc,
567 );
568 }
569 }
570 KnownPointer::Rc => {
571 let rc: Rc<str> = Rc::from(string_value.into_boxed_str());
572 unsafe {
573 core::ptr::write(
574 parent_frame.data.as_mut_byte_ptr() as *mut Rc<str>,
575 rc,
576 );
577 }
578 }
579 _ => {
580 return Err(ReflectError::OperationFailed {
581 shape: parent_shape,
582 operation: "Don't know how to build this pointer type",
583 });
584 }
585 }
586
587 parent_frame.tracker = Tracker::Init;
588
589 popped_frame.tracker = Tracker::Uninit;
590 popped_frame.dealloc();
591 }
592 _ => {
593 unreachable!(
594 "we popped a frame and parent was Init or Uninit, but it wasn't a smart pointer and... there's no way this should happen normally"
595 )
596 }
597 }
598 }
599 Tracker::SmartPointerSlice {
600 vtable,
601 building_item,
602 } => {
603 if *building_item {
604 let element_ptr = PtrMut::new(unsafe {
606 NonNull::new_unchecked(popped_frame.data.as_mut_byte_ptr())
607 });
608
609 crate::trace!("Pushing element to slice builder");
611 unsafe {
612 let parent_ptr = parent_frame.data.assume_init();
613 (vtable.push_fn)(parent_ptr, element_ptr);
614 }
615
616 popped_frame.tracker = Tracker::Uninit;
617 popped_frame.dealloc();
618
619 if let Tracker::SmartPointerSlice {
620 building_item: bi, ..
621 } = &mut parent_frame.tracker
622 {
623 *bi = false;
624 }
625 }
626 }
627 _ => {}
628 }
629
630 Ok(self)
631 }
632
633 pub fn path(&self) -> String {
636 let mut out = String::new();
637
638 let mut path_components = Vec::new();
639 for (i, frame) in self.frames.iter().enumerate() {
642 match frame.shape.ty {
643 Type::User(user_type) => match user_type {
644 UserType::Struct(struct_type) => {
645 let mut field_str = None;
647 if let Tracker::Struct {
648 current_child: Some(idx),
649 ..
650 } = &frame.tracker
651 {
652 if let Some(field) = struct_type.fields.get(*idx) {
653 field_str = Some(field.name);
654 }
655 }
656 if i == 0 {
657 path_components.push(format!("{}", frame.shape));
659 }
660 if let Some(field_name) = field_str {
661 path_components.push(format!(".{field_name}"));
662 }
663 }
664 UserType::Enum(_enum_type) => {
665 if let Tracker::Enum {
667 variant,
668 current_child,
669 ..
670 } = &frame.tracker
671 {
672 if i == 0 {
673 path_components.push(format!("{}", frame.shape));
675 }
676 path_components.push(format!("::{}", variant.name));
677 if let Some(idx) = *current_child {
678 if let Some(field) = variant.data.fields.get(idx) {
679 path_components.push(format!(".{}", field.name));
680 }
681 }
682 } else if i == 0 {
683 path_components.push(format!("{}", frame.shape));
685 }
686 }
687 UserType::Union(_union_type) => {
688 path_components.push(format!("{}", frame.shape));
689 }
690 UserType::Opaque => {
691 path_components.push("<opaque>".to_string());
692 }
693 },
694 Type::Sequence(seq_type) => match seq_type {
695 facet_core::SequenceType::Array(_array_def) => {
696 if let Tracker::Array {
698 current_child: Some(idx),
699 ..
700 } = &frame.tracker
701 {
702 path_components.push(format!("[{idx}]"));
703 }
704 }
705 _ => {
707 path_components.push("[]".to_string());
709 }
710 },
711 Type::Pointer(_) => {
712 path_components.push("*".to_string());
714 }
715 _ => {
716 }
718 }
719 }
720 for component in path_components {
722 out.push_str(&component);
723 }
724 out
725 }
726
727 pub fn parent_field(&self) -> Option<&Field> {
729 self.frames.iter().rev().nth(1).and_then(|f| f.get_field())
730 }
731}
732
733impl<'facet> Partial<'facet> {
737 pub fn build(&mut self) -> Result<HeapValue<'facet>, ReflectError> {
739 self.require_active()?;
740 if self.frames.len() != 1 {
741 self.state = PartialState::BuildFailed;
742 return Err(ReflectError::InvariantViolation {
743 invariant: "Partial::build() expects a single frame — call end() until that's the case",
744 });
745 }
746
747 let frame = self.frames.pop().unwrap();
748
749 if let Err(e) = frame.require_full_initialization() {
751 self.frames.push(frame);
753 self.state = PartialState::BuildFailed;
754 return Err(e);
755 }
756
757 if let Some(invariants_fn) = frame.shape.vtable.invariants {
759 let value_ptr = unsafe { frame.data.assume_init().as_const() };
761 let invariants_ok = unsafe { invariants_fn(value_ptr) };
762
763 if !invariants_ok {
764 self.frames.push(frame);
766 self.state = PartialState::BuildFailed;
767 return Err(ReflectError::InvariantViolation {
768 invariant: "Type invariants check failed",
769 });
770 }
771 }
772
773 self.state = PartialState::Built;
775
776 match frame
777 .shape
778 .layout
779 .sized_layout()
780 .map_err(|_layout_err| ReflectError::Unsized {
781 shape: frame.shape,
782 operation: "build (final check for sized layout)",
783 }) {
784 Ok(layout) => Ok(HeapValue {
785 guard: Some(Guard {
786 ptr: unsafe { NonNull::new_unchecked(frame.data.as_mut_byte_ptr()) },
787 layout,
788 }),
789 shape: frame.shape,
790 phantom: PhantomData,
791 }),
792 Err(e) => {
793 self.frames.push(frame);
795 self.state = PartialState::BuildFailed;
796 Err(e)
797 }
798 }
799 }
800}
801
802impl<'facet> Partial<'facet> {
806 pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
812 where
813 U: Facet<'facet>,
814 {
815 self.require_active()?;
816 struct DropVal<U> {
817 ptr: *mut U,
818 }
819 impl<U> Drop for DropVal<U> {
820 #[inline]
821 fn drop(&mut self) {
822 unsafe { core::ptr::drop_in_place(self.ptr) };
823 }
824 }
825
826 let mut value = ManuallyDrop::new(value);
827 let drop = DropVal {
828 ptr: (&mut value) as *mut ManuallyDrop<U> as *mut U,
829 };
830
831 let ptr_const = PtrConst::new(unsafe { NonNull::new_unchecked(drop.ptr) });
832 unsafe {
833 self.set_shape(ptr_const, U::SHAPE)?
835 };
836 core::mem::forget(drop);
837
838 Ok(self)
839 }
840
841 #[inline]
855 pub unsafe fn set_shape(
856 &mut self,
857 src_value: PtrConst<'_>,
858 src_shape: &'static Shape,
859 ) -> Result<&mut Self, ReflectError> {
860 self.require_active()?;
861
862 let fr = self.frames.last_mut().unwrap();
863 crate::trace!("set_shape({src_shape:?})");
864
865 if !fr.shape.is_shape(src_shape) {
866 return Err(ReflectError::WrongShape {
867 expected: fr.shape,
868 actual: src_shape,
869 });
870 }
871
872 fr.deinit();
873
874 unsafe {
877 fr.data.copy_from(src_value, fr.shape).unwrap();
880 }
881
882 unsafe {
884 fr.mark_as_init();
885 }
886
887 Ok(self)
888 }
889
890 pub unsafe fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
900 where
901 F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
902 {
903 self.require_active()?;
904 let frame = self.frames.last_mut().unwrap();
905
906 frame.deinit();
907 f(frame.data)?;
908
909 unsafe {
911 frame.mark_as_init();
912 }
913
914 Ok(self)
915 }
916
917 #[inline]
926 pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
927 let frame = self.frames.last().unwrap();
928
929 let Some(default_fn) = frame.shape.vtable.default_in_place else {
930 return Err(ReflectError::OperationFailed {
931 shape: frame.shape,
932 operation: "type does not implement Default",
933 });
934 };
935
936 unsafe {
939 self.set_from_function(move |ptr| {
940 default_fn(ptr);
941 Ok(())
942 })
943 }
944 }
945
946 pub unsafe fn set_from_peek(&mut self, peek: &Peek<'_, '_>) -> Result<&mut Self, ReflectError> {
957 self.require_active()?;
958
959 let src_ptr = peek.data();
961 let src_shape = peek.shape();
962
963 unsafe { self.set_shape(src_ptr, src_shape) }
965 }
966
967 pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
971 self.require_active()?;
972
973 let frame = self.frames.last_mut().unwrap();
974
975 let Some(parse_fn) = frame.shape.vtable.parse else {
977 return Err(ReflectError::OperationFailed {
978 shape: frame.shape,
979 operation: "Type does not support parsing from string",
980 });
981 };
982
983 frame.deinit();
985
986 let result = unsafe { parse_fn(s, frame.data) };
988 if let Err(_pe) = result {
989 return Err(ReflectError::OperationFailed {
991 shape: frame.shape,
992 operation: "Failed to parse string value",
993 });
994 }
995
996 unsafe {
998 frame.mark_as_init();
999 }
1000 Ok(self)
1001 }
1002}
1003
1004impl<'facet> Partial<'facet> {
1008 pub fn selected_variant(&self) -> Option<Variant> {
1010 let frame = self.frames.last()?;
1011
1012 match &frame.tracker {
1013 Tracker::Enum { variant, .. } => Some(**variant),
1014 _ => None,
1015 }
1016 }
1017
1018 pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'static Variant)> {
1020 let frame = self.frames.last()?;
1021
1022 if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
1023 enum_def
1024 .variants
1025 .iter()
1026 .enumerate()
1027 .find(|(_, v)| v.name == variant_name)
1028 } else {
1029 None
1030 }
1031 }
1032
1033 pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
1049 self.require_active()?;
1050
1051 let frame = self.frames.last().unwrap();
1052 let enum_type = frame.get_enum_type()?;
1053
1054 if index >= enum_type.variants.len() {
1055 return Err(ReflectError::OperationFailed {
1056 shape: frame.shape,
1057 operation: "variant index out of bounds",
1058 });
1059 }
1060 let variant = &enum_type.variants[index];
1061
1062 self.select_variant_internal(&enum_type, variant)?;
1063 Ok(self)
1064 }
1065
1066 pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
1070 self.require_active()?;
1071
1072 let frame = self.frames.last_mut().unwrap();
1073 let enum_type = frame.get_enum_type()?;
1074
1075 let Some(variant) = enum_type.variants.iter().find(|v| v.name == variant_name) else {
1076 return Err(ReflectError::OperationFailed {
1077 shape: frame.shape,
1078 operation: "No variant found with the given name",
1079 });
1080 };
1081
1082 self.select_variant_internal(&enum_type, variant)?;
1083 Ok(self)
1084 }
1085
1086 pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
1091 self.require_active()?;
1092
1093 let frame = self.frames.last().unwrap();
1095
1096 let enum_type = match frame.shape.ty {
1098 Type::User(UserType::Enum(e)) => e,
1099 _ => {
1100 return Err(ReflectError::WasNotA {
1101 expected: "enum",
1102 actual: frame.shape,
1103 });
1104 }
1105 };
1106
1107 let Some(variant) = enum_type
1109 .variants
1110 .iter()
1111 .find(|v| v.discriminant == Some(discriminant))
1112 else {
1113 return Err(ReflectError::OperationFailed {
1114 shape: frame.shape,
1115 operation: "No variant found with the given discriminant",
1116 });
1117 };
1118
1119 self.select_variant_internal(&enum_type, variant)?;
1121
1122 Ok(self)
1123 }
1124}
1125
1126impl Partial<'_> {
1130 pub fn field_index(&self, field_name: &str) -> Option<usize> {
1135 let frame = self.frames.last()?;
1136
1137 match frame.shape.ty {
1138 Type::User(UserType::Struct(struct_def)) => {
1139 struct_def.fields.iter().position(|f| f.name == field_name)
1140 }
1141 Type::User(UserType::Enum(_)) => {
1142 if let Tracker::Enum { variant, .. } = &frame.tracker {
1144 variant
1145 .data
1146 .fields
1147 .iter()
1148 .position(|f| f.name == field_name)
1149 } else {
1150 None
1151 }
1152 }
1153 _ => None,
1154 }
1155 }
1156
1157 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
1159 let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
1160
1161 match &frame.tracker {
1162 Tracker::Uninit => Ok(false),
1163 Tracker::Init => Ok(true),
1164 Tracker::Struct { iset, .. } => Ok(iset.get(index)),
1165 Tracker::Enum { data, variant, .. } => {
1166 if data.get(index) {
1168 return Ok(true);
1169 }
1170
1171 if let Some(field) = variant.data.fields.get(index) {
1173 if let Type::User(UserType::Struct(field_struct)) = field.shape().ty {
1174 if field_struct.fields.is_empty() {
1175 return Ok(true);
1176 }
1177 }
1178 }
1179
1180 Ok(false)
1181 }
1182 Tracker::Option { building_inner } => {
1183 if index == 0 {
1185 Ok(!building_inner)
1186 } else {
1187 Err(ReflectError::InvalidOperation {
1188 operation: "is_field_set",
1189 reason: "Option only has one field (index 0)",
1190 })
1191 }
1192 }
1193 _ => Err(ReflectError::InvalidOperation {
1194 operation: "is_field_set",
1195 reason: "Current frame is not a struct, enum variant, or option",
1196 }),
1197 }
1198 }
1199
1200 pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
1205 self.require_active()?;
1206
1207 let frame = self.frames.last().unwrap();
1208 let fields = self.get_fields()?;
1209 let Some(idx) = fields.iter().position(|f| f.name == field_name) else {
1210 return Err(ReflectError::FieldError {
1211 shape: frame.shape,
1212 field_error: facet_core::FieldError::NoSuchField,
1213 });
1214 };
1215 self.begin_nth_field(idx)
1216 }
1217
1218 pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1222 self.require_active()?;
1223 let frame = self.frames.last_mut().unwrap();
1224
1225 let next_frame = match frame.shape.ty {
1226 Type::User(user_type) => match user_type {
1227 UserType::Struct(struct_type) => {
1228 Self::begin_nth_struct_field(frame, struct_type, idx)?
1229 }
1230 UserType::Enum(_) => {
1231 match &frame.tracker {
1233 Tracker::Enum { variant, .. } => {
1234 Self::begin_nth_enum_field(frame, variant, idx)?
1235 }
1236 _ => {
1237 return Err(ReflectError::OperationFailed {
1238 shape: frame.shape,
1239 operation: "must call select_variant before selecting enum fields",
1240 });
1241 }
1242 }
1243 }
1244 UserType::Union(_) => {
1245 return Err(ReflectError::OperationFailed {
1246 shape: frame.shape,
1247 operation: "cannot select a field from a union",
1248 });
1249 }
1250 UserType::Opaque => {
1251 return Err(ReflectError::OperationFailed {
1252 shape: frame.shape,
1253 operation: "cannot select a field from an opaque type",
1254 });
1255 }
1256 },
1257 Type::Sequence(sequence_type) => match sequence_type {
1258 SequenceType::Array(array_type) => {
1259 Self::begin_nth_array_element(frame, array_type, idx)?
1260 }
1261 SequenceType::Slice(_) => {
1262 return Err(ReflectError::OperationFailed {
1263 shape: frame.shape,
1264 operation: "cannot select a field from slices yet",
1265 });
1266 }
1267 },
1268 _ => {
1269 return Err(ReflectError::OperationFailed {
1270 shape: frame.shape,
1271 operation: "cannot select a field from this type",
1272 });
1273 }
1274 };
1275
1276 self.frames.push(next_frame);
1277 Ok(self)
1278 }
1279
1280 pub fn set_nth_field_to_default(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1289 self.require_active()?;
1290
1291 let frame = self.frames.last().unwrap();
1292 let fields = self.get_fields()?;
1293
1294 if idx >= fields.len() {
1295 return Err(ReflectError::OperationFailed {
1296 shape: frame.shape,
1297 operation: "field index out of bounds",
1298 });
1299 }
1300
1301 let field = fields[idx];
1302
1303 if let Some(field_default_fn) = field.vtable.default_fn {
1305 self.begin_nth_field(idx)?;
1306 unsafe {
1308 self.set_from_function(|ptr| {
1309 field_default_fn(ptr);
1310 Ok(())
1311 })?;
1312 }
1313 self.end()
1314 } else if field.shape().is(Characteristic::Default) {
1315 self.begin_nth_field(idx)?;
1316 self.set_default()?;
1317 self.end()
1318 } else {
1319 return Err(ReflectError::DefaultAttrButNoDefaultImpl {
1320 shape: field.shape(),
1321 });
1322 }
1323 }
1324
1325 pub fn steal_nth_field(
1329 &mut self,
1330 src: &mut Partial,
1331 field_index: usize,
1332 ) -> Result<&mut Self, ReflectError> {
1333 let dst_shape = self.shape();
1334 let src_shape = src.shape();
1335 if dst_shape != src_shape {
1336 return Err(ReflectError::HeistCancelledDifferentShapes {
1337 src_shape,
1338 dst_shape,
1339 });
1340 }
1341
1342 if !src.is_field_set(field_index)? {
1345 return Err(ReflectError::InvariantViolation {
1346 invariant: "stolen field must be initialized",
1347 });
1348 }
1349
1350 let maybe_fields = match src_shape.ty {
1351 Type::Primitive(_primitive_type) => None,
1352 Type::Sequence(_sequence_type) => None,
1353 Type::User(user_type) => match user_type {
1354 UserType::Struct(struct_type) => Some(struct_type.fields),
1355 UserType::Enum(_enum_type) => match self.selected_variant() {
1356 Some(variant) => Some(variant.data.fields),
1357 None => {
1358 return Err(ReflectError::InvariantViolation {
1359 invariant: "enum field thief must have variant selected",
1360 });
1361 }
1362 },
1363 UserType::Union(_union_type) => None,
1364 UserType::Opaque => None,
1365 },
1366 Type::Pointer(_pointer_type) => None,
1367 };
1368
1369 let Some(fields) = maybe_fields else {
1370 return Err(ReflectError::OperationFailed {
1371 shape: src_shape,
1372 operation: "fetching field list for steal_nth_field",
1373 });
1374 };
1375
1376 if field_index >= fields.len() {
1377 return Err(ReflectError::OperationFailed {
1378 shape: src_shape,
1379 operation: "field index out of bounds",
1380 });
1381 }
1382 let field = fields[field_index];
1383
1384 let src_frame = src.frames.last_mut().unwrap();
1385
1386 self.begin_nth_field(field_index)?;
1387 unsafe {
1388 self.set_from_function(|dst_field_ptr| {
1389 let src_field_ptr = src_frame.data.field_init_at(field.offset).as_const();
1390 dst_field_ptr
1391 .copy_from(src_field_ptr, field.shape())
1392 .unwrap();
1393 Ok(())
1394 })?;
1395 }
1396 self.end()?;
1397
1398 match &mut src_frame.tracker {
1400 Tracker::Uninit => {
1401 unreachable!("we just stole a field from src, it couldn't have been fully uninit")
1402 }
1403 Tracker::Init => {
1404 let mut iset = ISet::new(fields.len());
1407 iset.set_all();
1408 iset.unset(field_index);
1409 src_frame.tracker = Tracker::Struct {
1410 iset,
1411 current_child: None,
1412 }
1413 }
1414 Tracker::Array { .. } => unreachable!("can't steal fields from arrays"),
1415 Tracker::Struct { iset, .. } => {
1416 iset.unset(field_index);
1417 }
1418 Tracker::SmartPointer { .. } => {
1419 unreachable!("can't steal fields from smart pointers")
1420 }
1421 Tracker::SmartPointerSlice { .. } => {
1422 unreachable!("can't steal fields from smart pointer slices")
1423 }
1424 Tracker::Enum { data, .. } => {
1425 data.unset(field_index);
1426 }
1427 Tracker::List { .. } => {
1428 unreachable!("can't steal fields from lists")
1429 }
1430 Tracker::Map { .. } => {
1431 unreachable!("can't steal fields from maps")
1432 }
1433 Tracker::Set { .. } => {
1434 unreachable!("can't steal fields from sets")
1435 }
1436 Tracker::Option { .. } => {
1437 unreachable!("can't steal fields from options")
1438 }
1439 }
1440
1441 Ok(self)
1442 }
1443}
1444
1445impl Partial<'_> {
1449 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
1451 crate::trace!("begin_smart_ptr()");
1452 self.require_active()?;
1453 let frame = self.frames.last_mut().unwrap();
1454
1455 match &frame.shape.def {
1457 Def::Pointer(smart_ptr_def) if smart_ptr_def.constructible_from_pointee() => {
1458 let pointee_shape = match smart_ptr_def.pointee() {
1460 Some(shape) => shape,
1461 None => {
1462 return Err(ReflectError::OperationFailed {
1463 shape: frame.shape,
1464 operation: "Smart pointer must have a pointee shape",
1465 });
1466 }
1467 };
1468
1469 if pointee_shape.layout.sized_layout().is_ok() {
1470 if matches!(frame.tracker, Tracker::Uninit) {
1474 frame.tracker = Tracker::SmartPointer {
1475 is_initialized: false,
1476 };
1477 }
1478
1479 let inner_layout = match pointee_shape.layout.sized_layout() {
1480 Ok(layout) => layout,
1481 Err(_) => {
1482 return Err(ReflectError::Unsized {
1483 shape: pointee_shape,
1484 operation: "begin_smart_ptr, calculating inner value layout",
1485 });
1486 }
1487 };
1488 let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1489 let Some(inner_ptr) = NonNull::new(inner_ptr) else {
1490 return Err(ReflectError::OperationFailed {
1491 shape: frame.shape,
1492 operation: "failed to allocate memory for smart pointer inner value",
1493 });
1494 };
1495
1496 self.frames.push(Frame::new(
1498 PtrUninit::new(inner_ptr),
1499 pointee_shape,
1500 FrameOwnership::Owned,
1501 ));
1502 } else {
1503 if pointee_shape == str::SHAPE {
1505 crate::trace!("Pointee is str");
1506
1507 let string_layout = String::SHAPE
1509 .layout
1510 .sized_layout()
1511 .expect("String must have a sized layout");
1512 let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1513 let Some(string_ptr) = NonNull::new(string_ptr) else {
1514 return Err(ReflectError::OperationFailed {
1515 shape: frame.shape,
1516 operation: "failed to allocate memory for string",
1517 });
1518 };
1519 let mut frame = Frame::new(
1520 PtrUninit::new(string_ptr),
1521 String::SHAPE,
1522 FrameOwnership::Owned,
1523 );
1524 frame.tracker = Tracker::Uninit;
1525 self.frames.push(frame);
1526 } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1527 crate::trace!("Pointee is [{}]", _st.t);
1528
1529 let slice_builder_vtable = smart_ptr_def
1531 .vtable
1532 .slice_builder_vtable
1533 .ok_or(ReflectError::OperationFailed {
1534 shape: frame.shape,
1535 operation: "smart pointer does not support slice building",
1536 })?;
1537
1538 let builder_ptr = (slice_builder_vtable.new_fn)();
1540
1541 if let FrameOwnership::Owned = frame.ownership {
1543 if let Ok(layout) = frame.shape.layout.sized_layout() {
1544 if layout.size() > 0 {
1545 unsafe {
1546 alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1547 };
1548 }
1549 }
1550 }
1551
1552 frame.data = builder_ptr.as_uninit();
1554 frame.tracker = Tracker::SmartPointerSlice {
1555 vtable: slice_builder_vtable,
1556 building_item: false,
1557 };
1558 frame.ownership = FrameOwnership::ManagedElsewhere;
1560 } else {
1561 return Err(ReflectError::OperationFailed {
1562 shape: frame.shape,
1563 operation: "push_smart_ptr can only be called on pointers to supported pointee types",
1564 });
1565 }
1566 }
1567
1568 Ok(self)
1569 }
1570 _ => Err(ReflectError::OperationFailed {
1571 shape: frame.shape,
1572 operation: "push_smart_ptr can only be called on compatible types",
1573 }),
1574 }
1575 }
1576}
1577
1578impl Partial<'_> {
1582 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1590 crate::trace!("begin_list()");
1591 self.require_active()?;
1592 let frame = self.frames.last_mut().unwrap();
1593
1594 match &frame.tracker {
1595 Tracker::Uninit => {
1596 }
1598 Tracker::Init => {
1599 frame.tracker = Tracker::List {
1601 is_initialized: true,
1602 current_child: false,
1603 };
1604 return Ok(self);
1605 }
1606 Tracker::List { is_initialized, .. } => {
1607 if *is_initialized {
1608 return Ok(self);
1610 }
1611 }
1612 Tracker::SmartPointerSlice { .. } => {
1613 return Ok(self);
1615 }
1616 _ => {
1617 return Err(ReflectError::UnexpectedTracker {
1618 message: "begin_list called but tracker isn't something list-like",
1619 current_tracker: frame.tracker.kind(),
1620 });
1621 }
1622 };
1623
1624 let list_def = match &frame.shape.def {
1626 Def::List(list_def) => list_def,
1627 _ => {
1628 return Err(ReflectError::OperationFailed {
1629 shape: frame.shape,
1630 operation: "begin_list can only be called on List types",
1631 });
1632 }
1633 };
1634
1635 let init_fn = match list_def.vtable.init_in_place_with_capacity {
1637 Some(f) => f,
1638 None => {
1639 return Err(ReflectError::OperationFailed {
1640 shape: frame.shape,
1641 operation: "list type does not support initialization with capacity",
1642 });
1643 }
1644 };
1645
1646 unsafe {
1648 init_fn(frame.data, 0);
1649 }
1650
1651 frame.tracker = Tracker::List {
1653 is_initialized: true,
1654 current_child: false,
1655 };
1656
1657 Ok(self)
1658 }
1659
1660 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1663 crate::trace!("begin_list_item()");
1664 self.require_active()?;
1665 let frame = self.frames.last_mut().unwrap();
1666
1667 if let Tracker::SmartPointerSlice {
1669 building_item,
1670 vtable: _,
1671 } = &frame.tracker
1672 {
1673 if *building_item {
1674 return Err(ReflectError::OperationFailed {
1675 shape: frame.shape,
1676 operation: "already building an item, call end() first",
1677 });
1678 }
1679
1680 let element_shape = match &frame.shape.def {
1682 Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1683 Some(pointee_shape) => match &pointee_shape.ty {
1684 Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1685 _ => {
1686 return Err(ReflectError::OperationFailed {
1687 shape: frame.shape,
1688 operation: "smart pointer pointee is not a slice",
1689 });
1690 }
1691 },
1692 None => {
1693 return Err(ReflectError::OperationFailed {
1694 shape: frame.shape,
1695 operation: "smart pointer has no pointee",
1696 });
1697 }
1698 },
1699 _ => {
1700 return Err(ReflectError::OperationFailed {
1701 shape: frame.shape,
1702 operation: "expected smart pointer definition",
1703 });
1704 }
1705 };
1706
1707 crate::trace!("Pointee is a slice of {element_shape}");
1709 let element_layout = match element_shape.layout.sized_layout() {
1710 Ok(layout) => layout,
1711 Err(_) => {
1712 return Err(ReflectError::OperationFailed {
1713 shape: element_shape,
1714 operation: "cannot allocate unsized element",
1715 });
1716 }
1717 };
1718
1719 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1720 let Some(element_ptr) = NonNull::new(element_ptr) else {
1721 return Err(ReflectError::OperationFailed {
1722 shape: frame.shape,
1723 operation: "failed to allocate memory for list element",
1724 });
1725 };
1726
1727 crate::trace!("Pushing element frame, which we just allocated");
1729 let element_frame = Frame::new(
1730 PtrUninit::new(element_ptr),
1731 element_shape,
1732 FrameOwnership::Owned,
1733 );
1734 self.frames.push(element_frame);
1735
1736 let parent_idx = self.frames.len() - 2;
1739 if let Tracker::SmartPointerSlice { building_item, .. } =
1740 &mut self.frames[parent_idx].tracker
1741 {
1742 crate::trace!("Marking element frame as building item");
1743 *building_item = true;
1744 }
1745
1746 return Ok(self);
1747 }
1748
1749 let list_def = match &frame.shape.def {
1751 Def::List(list_def) => list_def,
1752 _ => {
1753 return Err(ReflectError::OperationFailed {
1754 shape: frame.shape,
1755 operation: "push can only be called on List types",
1756 });
1757 }
1758 };
1759
1760 match &mut frame.tracker {
1762 Tracker::List {
1763 is_initialized: true,
1764 current_child,
1765 } => {
1766 if *current_child {
1767 return Err(ReflectError::OperationFailed {
1768 shape: frame.shape,
1769 operation: "already pushing an element, call pop() first",
1770 });
1771 }
1772 *current_child = true;
1773 }
1774 _ => {
1775 return Err(ReflectError::OperationFailed {
1776 shape: frame.shape,
1777 operation: "must call begin_list() before push()",
1778 });
1779 }
1780 }
1781
1782 let element_shape = list_def.t();
1784
1785 let element_layout = match element_shape.layout.sized_layout() {
1787 Ok(layout) => layout,
1788 Err(_) => {
1789 return Err(ReflectError::Unsized {
1790 shape: element_shape,
1791 operation: "begin_list_item: calculating element layout",
1792 });
1793 }
1794 };
1795 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1796
1797 let Some(element_ptr) = NonNull::new(element_ptr) else {
1798 return Err(ReflectError::OperationFailed {
1799 shape: frame.shape,
1800 operation: "failed to allocate memory for list element",
1801 });
1802 };
1803
1804 self.frames.push(Frame::new(
1806 PtrUninit::new(element_ptr),
1807 element_shape,
1808 FrameOwnership::Owned,
1809 ));
1810
1811 Ok(self)
1812 }
1813}
1814
1815impl Partial<'_> {
1819 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1824 self.require_active()?;
1825 let frame = self.frames.last_mut().unwrap();
1826
1827 let map_def = match &frame.shape.def {
1829 Def::Map(map_def) => map_def,
1830 _ => {
1831 return Err(ReflectError::OperationFailed {
1832 shape: frame.shape,
1833 operation: "begin_map can only be called on Map types",
1834 });
1835 }
1836 };
1837
1838 let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1839
1840 unsafe {
1842 init_fn(frame.data, 0);
1843 }
1844
1845 frame.tracker = Tracker::Map {
1847 is_initialized: true,
1848 insert_state: MapInsertState::Idle,
1849 };
1850
1851 Ok(self)
1852 }
1853
1854 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1858 self.require_active()?;
1859 let frame = self.frames.last_mut().unwrap();
1860
1861 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1863 (
1864 Def::Map(map_def),
1865 Tracker::Map {
1866 is_initialized: true,
1867 insert_state,
1868 },
1869 ) => {
1870 match insert_state {
1871 MapInsertState::Idle => {
1872 *insert_state = MapInsertState::PushingKey { key_ptr: None };
1874 }
1875 MapInsertState::PushingKey { key_ptr } => {
1876 if key_ptr.is_some() {
1877 return Err(ReflectError::OperationFailed {
1878 shape: frame.shape,
1879 operation: "already pushing a key, call end() first",
1880 });
1881 }
1882 }
1883 _ => {
1884 return Err(ReflectError::OperationFailed {
1885 shape: frame.shape,
1886 operation: "must complete current operation before begin_key()",
1887 });
1888 }
1889 }
1890 map_def
1891 }
1892 _ => {
1893 return Err(ReflectError::OperationFailed {
1894 shape: frame.shape,
1895 operation: "must call begin_map() before begin_key()",
1896 });
1897 }
1898 };
1899
1900 let key_shape = map_def.k();
1902
1903 let key_layout = match key_shape.layout.sized_layout() {
1905 Ok(layout) => layout,
1906 Err(_) => {
1907 return Err(ReflectError::Unsized {
1908 shape: key_shape,
1909 operation: "begin_key allocating key",
1910 });
1911 }
1912 };
1913 let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1914
1915 let Some(key_ptr_raw) = NonNull::new(key_ptr_raw) else {
1916 return Err(ReflectError::OperationFailed {
1917 shape: frame.shape,
1918 operation: "failed to allocate memory for map key",
1919 });
1920 };
1921
1922 match &mut frame.tracker {
1924 Tracker::Map {
1925 insert_state: MapInsertState::PushingKey { key_ptr: kp },
1926 ..
1927 } => {
1928 *kp = Some(PtrUninit::new(key_ptr_raw));
1929 }
1930 _ => unreachable!(),
1931 }
1932
1933 self.frames.push(Frame::new(
1935 PtrUninit::new(key_ptr_raw),
1936 key_shape,
1937 FrameOwnership::ManagedElsewhere, ));
1939
1940 Ok(self)
1941 }
1942
1943 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1946 self.require_active()?;
1947 let frame = self.frames.last_mut().unwrap();
1948
1949 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1951 (
1952 Def::Map(map_def),
1953 Tracker::Map {
1954 insert_state: MapInsertState::PushingValue { value_ptr, .. },
1955 ..
1956 },
1957 ) => {
1958 if value_ptr.is_some() {
1959 return Err(ReflectError::OperationFailed {
1960 shape: frame.shape,
1961 operation: "already pushing a value, call pop() first",
1962 });
1963 }
1964 map_def
1965 }
1966 _ => {
1967 return Err(ReflectError::OperationFailed {
1968 shape: frame.shape,
1969 operation: "must complete key before push_value()",
1970 });
1971 }
1972 };
1973
1974 let value_shape = map_def.v();
1976
1977 let value_layout = match value_shape.layout.sized_layout() {
1979 Ok(layout) => layout,
1980 Err(_) => {
1981 return Err(ReflectError::Unsized {
1982 shape: value_shape,
1983 operation: "begin_value allocating value",
1984 });
1985 }
1986 };
1987 let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1988
1989 let Some(value_ptr_raw) = NonNull::new(value_ptr_raw) else {
1990 return Err(ReflectError::OperationFailed {
1991 shape: frame.shape,
1992 operation: "failed to allocate memory for map value",
1993 });
1994 };
1995
1996 match &mut frame.tracker {
1998 Tracker::Map {
1999 insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
2000 ..
2001 } => {
2002 *vp = Some(PtrUninit::new(value_ptr_raw));
2003 }
2004 _ => unreachable!(),
2005 }
2006
2007 self.frames.push(Frame::new(
2009 PtrUninit::new(value_ptr_raw),
2010 value_shape,
2011 FrameOwnership::ManagedElsewhere, ));
2013
2014 Ok(self)
2015 }
2016}
2017
2018impl Partial<'_> {
2022 pub fn begin_set(&mut self) -> Result<&mut Self, ReflectError> {
2029 crate::trace!("begin_set()");
2030 self.require_active()?;
2031 let frame = self.frames.last_mut().unwrap();
2032
2033 match &frame.tracker {
2034 Tracker::Uninit => {
2035 }
2037 Tracker::Init => {
2038 frame.tracker = Tracker::Set {
2040 is_initialized: true,
2041 current_child: false,
2042 };
2043 return Ok(self);
2044 }
2045 Tracker::Set { is_initialized, .. } => {
2046 if *is_initialized {
2047 return Ok(self);
2049 }
2050 }
2051 _ => {
2052 return Err(ReflectError::UnexpectedTracker {
2053 message: "begin_set called but tracker isn't something set-like",
2054 current_tracker: frame.tracker.kind(),
2055 });
2056 }
2057 };
2058
2059 let set_def = match &frame.shape.def {
2061 Def::Set(set_def) => set_def,
2062 _ => {
2063 return Err(ReflectError::OperationFailed {
2064 shape: frame.shape,
2065 operation: "begin_set can only be called on Set types",
2066 });
2067 }
2068 };
2069
2070 let init_fn = set_def.vtable.init_in_place_with_capacity_fn;
2071
2072 unsafe {
2074 init_fn(frame.data, 0);
2075 }
2076
2077 frame.tracker = Tracker::Set {
2079 is_initialized: true,
2080 current_child: false,
2081 };
2082
2083 Ok(self)
2084 }
2085
2086 pub fn begin_set_item(&mut self) -> Result<&mut Self, ReflectError> {
2089 crate::trace!("begin_set_item()");
2090 self.require_active()?;
2091 let frame = self.frames.last_mut().unwrap();
2092
2093 let set_def = match &frame.shape.def {
2095 Def::Set(set_def) => set_def,
2096 _ => {
2097 return Err(ReflectError::OperationFailed {
2098 shape: frame.shape,
2099 operation: "begin_set_item can only be called on Set types",
2100 });
2101 }
2102 };
2103
2104 match &mut frame.tracker {
2106 Tracker::Set {
2107 is_initialized: true,
2108 current_child,
2109 } => {
2110 if *current_child {
2111 return Err(ReflectError::OperationFailed {
2112 shape: frame.shape,
2113 operation: "already pushing an element, call end() first",
2114 });
2115 }
2116 *current_child = true;
2117 }
2118 _ => {
2119 return Err(ReflectError::OperationFailed {
2120 shape: frame.shape,
2121 operation: "must call begin_set() before begin_set_item()",
2122 });
2123 }
2124 }
2125
2126 let element_shape = set_def.t();
2128
2129 let element_layout = match element_shape.layout.sized_layout() {
2131 Ok(layout) => layout,
2132 Err(_) => {
2133 return Err(ReflectError::Unsized {
2134 shape: element_shape,
2135 operation: "begin_set_item: calculating element layout",
2136 });
2137 }
2138 };
2139 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
2140
2141 let Some(element_ptr) = NonNull::new(element_ptr) else {
2142 return Err(ReflectError::OperationFailed {
2143 shape: frame.shape,
2144 operation: "failed to allocate memory for set element",
2145 });
2146 };
2147
2148 self.frames.push(Frame::new(
2150 PtrUninit::new(element_ptr),
2151 element_shape,
2152 FrameOwnership::Owned,
2153 ));
2154
2155 Ok(self)
2156 }
2157}
2158
2159impl Partial<'_> {
2163 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
2165 self.require_active()?;
2166 let frame = self.frames.last_mut().unwrap();
2167
2168 let option_def = match frame.shape.def {
2170 Def::Option(def) => def,
2171 _ => {
2172 return Err(ReflectError::WasNotA {
2173 expected: "Option",
2174 actual: frame.shape,
2175 });
2176 }
2177 };
2178
2179 if matches!(frame.tracker, Tracker::Uninit) {
2181 frame.tracker = Tracker::Option {
2182 building_inner: true,
2183 };
2184 }
2185
2186 let inner_shape = option_def.t;
2188
2189 let inner_layout =
2191 inner_shape
2192 .layout
2193 .sized_layout()
2194 .map_err(|_| ReflectError::Unsized {
2195 shape: inner_shape,
2196 operation: "begin_some, allocating Option inner value",
2197 })?;
2198
2199 let inner_data = if inner_layout.size() == 0 {
2200 PtrUninit::new(NonNull::<u8>::dangling())
2202 } else {
2203 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2205 let Some(ptr) = NonNull::new(ptr) else {
2206 alloc::alloc::handle_alloc_error(inner_layout);
2207 };
2208 PtrUninit::new(ptr)
2209 };
2210
2211 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
2213 self.frames.push(inner_frame);
2214
2215 Ok(self)
2216 }
2217
2218 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
2220 self.require_active()?;
2221
2222 let (inner_shape, has_try_from, parent_shape) = {
2224 let frame = self.frames.last().unwrap();
2225 if let Some(inner_shape) = frame.shape.inner {
2226 let has_try_from = frame.shape.vtable.try_from.is_some();
2227 (Some(inner_shape), has_try_from, frame.shape)
2228 } else {
2229 (None, false, frame.shape)
2230 }
2231 };
2232
2233 if let Some(inner_shape) = inner_shape {
2234 if has_try_from {
2235 let inner_layout =
2242 inner_shape
2243 .layout
2244 .sized_layout()
2245 .map_err(|_| ReflectError::Unsized {
2246 shape: inner_shape,
2247 operation: "begin_inner, getting inner layout",
2248 })?;
2249
2250 let inner_data = if inner_layout.size() == 0 {
2251 PtrUninit::new(NonNull::<u8>::dangling())
2253 } else {
2254 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2256 let Some(ptr) = NonNull::new(ptr) else {
2257 alloc::alloc::handle_alloc_error(inner_layout);
2258 };
2259 PtrUninit::new(ptr)
2260 };
2261
2262 trace!(
2266 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
2267 );
2268 self.frames
2269 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2270
2271 Ok(self)
2272 } else {
2273 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
2276 self.begin_nth_field(0)
2277 }
2278 } else {
2279 Err(ReflectError::OperationFailed {
2280 shape: parent_shape,
2281 operation: "type does not have an inner value",
2282 })
2283 }
2284 }
2285
2286 pub fn begin_custom_deserialization(&mut self) -> Result<&mut Self, ReflectError> {
2289 self.require_active()?;
2290
2291 let current_frame = self.frames.last().unwrap();
2292 let target_shape = current_frame.shape;
2293 if let Some(field) = self.parent_field() {
2294 if field.vtable.deserialize_with.is_some() {
2295 let Some(FieldAttribute::DeserializeFrom(source_shape)) = field
2298 .attributes
2299 .iter()
2300 .find(|&p| matches!(p, FieldAttribute::DeserializeFrom(_)))
2301 else {
2302 panic!("expected field attribute to be present with deserialize_with");
2303 };
2304 let source_data = source_shape.allocate().map_err(|_| ReflectError::Unsized {
2305 shape: target_shape,
2306 operation: "Not a Sized type",
2307 })?;
2308
2309 trace!(
2310 "begin_custom_deserialization: Creating frame for deserialization type {source_shape}"
2311 );
2312 let mut new_frame = Frame::new(source_data, source_shape, FrameOwnership::Owned);
2313 new_frame.using_custom_deserialization = true;
2314 self.frames.push(new_frame);
2315
2316 Ok(self)
2317 } else {
2318 Err(ReflectError::OperationFailed {
2319 shape: target_shape,
2320 operation: "field does not have a deserialize_with function",
2321 })
2322 }
2323 } else {
2324 Err(ReflectError::OperationFailed {
2325 shape: target_shape,
2326 operation: "not currently processing a field",
2327 })
2328 }
2329 }
2330}
2331
2332impl<'facet> Partial<'facet> {
2336 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2340 where
2341 U: Facet<'facet>,
2342 {
2343 self.begin_nth_field(idx)?.set(value)?.end()
2344 }
2345
2346 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
2348 where
2349 U: Facet<'facet>,
2350 {
2351 self.begin_field(field_name)?.set(value)?.end()
2352 }
2353
2354 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2356 where
2357 U: Facet<'facet>,
2358 {
2359 self.begin_key()?.set(value)?.end()
2360 }
2361
2362 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2364 where
2365 U: Facet<'facet>,
2366 {
2367 self.begin_value()?.set(value)?.end()
2368 }
2369
2370 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2372 where
2373 U: Facet<'facet>,
2374 {
2375 self.begin_list_item()?.set(value)?.end()
2376 }
2377
2378 pub fn insert<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2380 where
2381 U: Facet<'facet>,
2382 {
2383 self.begin_set_item()?.set(value)?.end()
2384 }
2385}
2386
2387impl<'facet> Partial<'facet> {
2391 fn select_variant_internal(
2400 &mut self,
2401 enum_type: &EnumType,
2402 variant: &'static Variant,
2403 ) -> Result<(), ReflectError> {
2404 let frame = self.frames.last().unwrap();
2406
2407 match enum_type.enum_repr {
2409 EnumRepr::RustNPO => {
2410 return Err(ReflectError::OperationFailed {
2411 shape: frame.shape,
2412 operation: "RustNPO enums are not supported for incremental building",
2413 });
2414 }
2415 EnumRepr::U8
2416 | EnumRepr::U16
2417 | EnumRepr::U32
2418 | EnumRepr::U64
2419 | EnumRepr::I8
2420 | EnumRepr::I16
2421 | EnumRepr::I32
2422 | EnumRepr::I64
2423 | EnumRepr::USize
2424 | EnumRepr::ISize => {
2425 }
2427 }
2428
2429 let Some(discriminant) = variant.discriminant else {
2430 return Err(ReflectError::OperationFailed {
2431 shape: frame.shape,
2432 operation: "trying to select an enum variant without a discriminant",
2433 });
2434 };
2435
2436 let fr = self.frames.last_mut().unwrap();
2438
2439 unsafe {
2441 match enum_type.enum_repr {
2442 EnumRepr::U8 => {
2443 let ptr = fr.data.as_mut_byte_ptr();
2444 *ptr = discriminant as u8;
2445 }
2446 EnumRepr::U16 => {
2447 let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
2448 *ptr = discriminant as u16;
2449 }
2450 EnumRepr::U32 => {
2451 let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
2452 *ptr = discriminant as u32;
2453 }
2454 EnumRepr::U64 => {
2455 let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
2456 *ptr = discriminant as u64;
2457 }
2458 EnumRepr::I8 => {
2459 let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
2460 *ptr = discriminant as i8;
2461 }
2462 EnumRepr::I16 => {
2463 let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
2464 *ptr = discriminant as i16;
2465 }
2466 EnumRepr::I32 => {
2467 let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
2468 *ptr = discriminant as i32;
2469 }
2470 EnumRepr::I64 => {
2471 let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
2472 *ptr = discriminant;
2473 }
2474 EnumRepr::USize => {
2475 let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
2476 *ptr = discriminant as usize;
2477 }
2478 EnumRepr::ISize => {
2479 let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
2480 *ptr = discriminant as isize;
2481 }
2482 _ => unreachable!("Already checked enum representation above"),
2483 }
2484 }
2485
2486 fr.tracker = Tracker::Enum {
2488 variant,
2489 data: ISet::new(variant.data.fields.len()),
2490 current_child: None,
2491 };
2492
2493 Ok(())
2494 }
2495
2496 fn get_fields(&self) -> Result<&'static [Field], ReflectError> {
2499 let frame = self.frames.last().unwrap();
2500 match frame.shape.ty {
2501 Type::Primitive(_) => Err(ReflectError::OperationFailed {
2502 shape: frame.shape,
2503 operation: "cannot select a field from a primitive type",
2504 }),
2505 Type::Sequence(_) => Err(ReflectError::OperationFailed {
2506 shape: frame.shape,
2507 operation: "cannot select a field from a sequence type",
2508 }),
2509 Type::User(user_type) => match user_type {
2510 UserType::Struct(struct_type) => Ok(struct_type.fields),
2511 UserType::Enum(_) => {
2512 let Tracker::Enum { variant, .. } = &frame.tracker else {
2513 return Err(ReflectError::OperationFailed {
2514 shape: frame.shape,
2515 operation: "must select variant before selecting enum fields",
2516 });
2517 };
2518 Ok(variant.data.fields)
2519 }
2520 UserType::Union(_) => Err(ReflectError::OperationFailed {
2521 shape: frame.shape,
2522 operation: "cannot select a field from a union type",
2523 }),
2524 UserType::Opaque => Err(ReflectError::OperationFailed {
2525 shape: frame.shape,
2526 operation: "opaque types cannot be reflected upon",
2527 }),
2528 },
2529 Type::Pointer(_) => Err(ReflectError::OperationFailed {
2530 shape: frame.shape,
2531 operation: "cannot select a field from a pointer type",
2532 }),
2533 }
2534 }
2535
2536 fn begin_nth_struct_field(
2538 frame: &mut Frame,
2539 struct_type: StructType,
2540 idx: usize,
2541 ) -> Result<Frame, ReflectError> {
2542 if idx >= struct_type.fields.len() {
2543 return Err(ReflectError::OperationFailed {
2544 shape: frame.shape,
2545 operation: "field index out of bounds",
2546 });
2547 }
2548 let field = &struct_type.fields[idx];
2549
2550 if !matches!(frame.tracker, Tracker::Struct { .. }) {
2551 frame.tracker = Tracker::Struct {
2552 iset: ISet::new(struct_type.fields.len()),
2553 current_child: None,
2554 }
2555 }
2556
2557 let was_field_init = match &mut frame.tracker {
2558 Tracker::Struct {
2559 iset,
2560 current_child,
2561 } => {
2562 *current_child = Some(idx);
2563 iset.get(idx)
2564 }
2565 _ => unreachable!(),
2566 };
2567
2568 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2570 let field_shape = field.shape();
2571
2572 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2573 if was_field_init {
2574 unsafe {
2575 next_frame.mark_as_init();
2577 }
2578 }
2579
2580 Ok(next_frame)
2581 }
2582
2583 fn begin_nth_array_element(
2585 frame: &mut Frame,
2586 array_type: ArrayType,
2587 idx: usize,
2588 ) -> Result<Frame, ReflectError> {
2589 if idx >= array_type.n {
2590 return Err(ReflectError::OperationFailed {
2591 shape: frame.shape,
2592 operation: "array index out of bounds",
2593 });
2594 }
2595
2596 if array_type.n > 63 {
2597 return Err(ReflectError::OperationFailed {
2598 shape: frame.shape,
2599 operation: "arrays larger than 63 elements are not yet supported",
2600 });
2601 }
2602
2603 match &frame.tracker {
2605 Tracker::Uninit => {
2606 frame.tracker = Tracker::Array {
2608 iset: ISet::default(),
2609 current_child: None,
2610 };
2611 }
2612 Tracker::Array { .. } => {
2613 }
2615 _other => {
2616 return Err(ReflectError::OperationFailed {
2617 shape: frame.shape,
2618 operation: "unexpected tracker state: expected Uninit or Array",
2619 });
2620 }
2621 }
2622
2623 match &mut frame.tracker {
2624 Tracker::Array {
2625 iset,
2626 current_child,
2627 } => {
2628 *current_child = Some(idx);
2629 let was_field_init = iset.get(idx);
2630
2631 let Ok(element_layout) = array_type.t.layout.sized_layout() else {
2633 return Err(ReflectError::Unsized {
2634 shape: array_type.t,
2635 operation: "begin_nth_element, calculating array element offset",
2636 });
2637 };
2638 let offset = element_layout.size() * idx;
2639 let element_data = unsafe { frame.data.field_uninit_at(offset) };
2640
2641 let mut next_frame = Frame::new(element_data, array_type.t, FrameOwnership::Field);
2642 if was_field_init {
2643 unsafe {
2645 next_frame.mark_as_init();
2646 }
2647 }
2648 Ok(next_frame)
2649 }
2650 _ => unreachable!(),
2651 }
2652 }
2653
2654 fn begin_nth_enum_field(
2656 frame: &mut Frame,
2657 variant: &'static Variant,
2658 idx: usize,
2659 ) -> Result<Frame, ReflectError> {
2660 if idx >= variant.data.fields.len() {
2661 return Err(ReflectError::OperationFailed {
2662 shape: frame.shape,
2663 operation: "enum field index out of bounds",
2664 });
2665 }
2666
2667 let field = &variant.data.fields[idx];
2668
2669 let was_field_init = match &mut frame.tracker {
2671 Tracker::Enum {
2672 data,
2673 current_child,
2674 ..
2675 } => {
2676 *current_child = Some(idx);
2677 data.get(idx)
2678 }
2679 _ => {
2680 return Err(ReflectError::OperationFailed {
2681 shape: frame.shape,
2682 operation: "selecting a field on an enum requires selecting a variant first",
2683 });
2684 }
2685 };
2686
2687 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2690 let field_shape = field.shape();
2691
2692 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2693 if was_field_init {
2694 unsafe {
2696 next_frame.mark_as_init();
2697 }
2698 }
2699
2700 Ok(next_frame)
2701 }
2702
2703 #[inline]
2705 pub(crate) fn require_active(&self) -> Result<(), ReflectError> {
2706 if self.state == PartialState::Active {
2707 Ok(())
2708 } else {
2709 Err(ReflectError::InvariantViolation {
2710 invariant: "Cannot use Partial after it has been built or poisoned",
2711 })
2712 }
2713 }
2714}