1use alloc::{
4 boxed::Box,
5 format,
6 string::{String, ToString},
7 vec::Vec,
8};
9
10use core::marker::PhantomData;
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, KnownPointer, PtrConst,
19 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(arc_ptr.as_byte_ptr() as *mut u8);
115 self.frames[0].tracker = Tracker::Init;
116 self.frames[0].ownership = FrameOwnership::ManagedElsewhere;
118
119 return Ok(self);
120 }
121 }
122
123 if self.frames.len() <= 1 {
124 return Err(ReflectError::InvariantViolation {
126 invariant: "Partial::end() called with only one frame on the stack",
127 });
128 }
129
130 {
132 let frame = self.frames.last().unwrap();
133 trace!(
134 "end(): Checking full initialization for frame with shape {} and tracker {:?}",
135 frame.shape,
136 frame.tracker.kind()
137 );
138 frame.require_full_initialization()?
139 }
140
141 let mut popped_frame = self.frames.pop().unwrap();
143
144 let parent_frame = self.frames.last_mut().unwrap();
146
147 trace!(
148 "end(): Popped {} (tracker {:?}), Parent {} (tracker {:?})",
149 popped_frame.shape,
150 popped_frame.tracker.kind(),
151 parent_frame.shape,
152 parent_frame.tracker.kind()
153 );
154
155 let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
160 && parent_frame.shape.inner.is_some()
161 && parent_frame.shape.inner.unwrap()() == popped_frame.shape
162 && parent_frame
163 .shape
164 .vtable
165 .sized()
166 .and_then(|v| (v.try_from)())
167 .is_some();
168
169 if needs_conversion {
170 trace!(
171 "Detected implicit conversion needed from {} to {}",
172 popped_frame.shape, parent_frame.shape
173 );
174 if let Some(try_from_fn) = parent_frame
176 .shape
177 .vtable
178 .sized()
179 .and_then(|v| (v.try_from)())
180 {
181 let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
182 let inner_shape = popped_frame.shape;
183
184 trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
185 let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
186
187 if let Err(e) = result {
188 trace!("Conversion failed: {e:?}");
189
190 if let FrameOwnership::Owned = popped_frame.ownership {
192 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
193 if layout.size() > 0 {
194 trace!(
195 "Deallocating conversion frame memory after failure: size={}, align={}",
196 layout.size(),
197 layout.align()
198 );
199 unsafe {
200 alloc::alloc::dealloc(
201 popped_frame.data.as_mut_byte_ptr(),
202 layout,
203 );
204 }
205 }
206 }
207 }
208
209 return Err(ReflectError::TryFromError {
210 src_shape: inner_shape,
211 dst_shape: parent_frame.shape,
212 inner: e,
213 });
214 }
215
216 trace!("Conversion succeeded, marking parent as initialized");
217 parent_frame.tracker = Tracker::Init;
218
219 if let FrameOwnership::Owned = popped_frame.ownership {
221 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
222 if layout.size() > 0 {
223 trace!(
224 "Deallocating conversion frame memory: size={}, align={}",
225 layout.size(),
226 layout.align()
227 );
228 unsafe {
229 alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
230 }
231 }
232 }
233 }
234
235 return Ok(self);
236 }
237 }
238
239 match &mut parent_frame.tracker {
240 Tracker::Struct {
241 iset,
242 current_child,
243 } => {
244 if let Some(idx) = *current_child {
245 iset.set(idx);
246 *current_child = None;
247 }
248 }
249 Tracker::Array {
250 iset,
251 current_child,
252 } => {
253 if let Some(idx) = *current_child {
254 iset.set(idx);
255 *current_child = None;
256 }
257 }
258 Tracker::SmartPointer { is_initialized } => {
259 if let Def::Pointer(smart_ptr_def) = parent_frame.shape.def {
261 let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn else {
262 return Err(ReflectError::OperationFailed {
263 shape: parent_frame.shape,
264 operation: "SmartPointer missing new_into_fn",
265 });
266 };
267
268 let inner_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
270
271 unsafe {
273 new_into_fn(parent_frame.data, inner_ptr);
274 }
275
276 popped_frame.tracker = Tracker::Uninit;
278
279 popped_frame.dealloc();
281
282 *is_initialized = true;
283 }
284 }
285 Tracker::Enum {
286 data,
287 current_child,
288 ..
289 } => {
290 if let Some(idx) = *current_child {
291 data.set(idx);
292 *current_child = None;
293 }
294 }
295 Tracker::List {
296 is_initialized: true,
297 current_child,
298 } => {
299 if *current_child {
300 if let Def::List(list_def) = parent_frame.shape.def {
302 let Some(push_fn) = list_def.vtable.push else {
303 return Err(ReflectError::OperationFailed {
304 shape: parent_frame.shape,
305 operation: "List missing push function",
306 });
307 };
308
309 let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
311
312 unsafe {
314 push_fn(
315 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
316 element_ptr,
317 );
318 }
319
320 popped_frame.tracker = Tracker::Uninit;
322 popped_frame.dealloc();
323
324 *current_child = false;
325 }
326 }
327 }
328 Tracker::Map {
329 is_initialized: true,
330 insert_state,
331 } => {
332 match insert_state {
333 MapInsertState::PushingKey { key_ptr } => {
334 if let Some(key_ptr) = key_ptr {
336 *insert_state = MapInsertState::PushingValue {
338 key_ptr: *key_ptr,
339 value_ptr: None,
340 };
341 }
342 }
343 MapInsertState::PushingValue { key_ptr, value_ptr } => {
344 if let (Some(value_ptr), Def::Map(map_def)) =
346 (value_ptr, parent_frame.shape.def)
347 {
348 let insert_fn = map_def.vtable.insert_fn;
349
350 unsafe {
352 insert_fn(
353 PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
354 PtrMut::new(key_ptr.as_mut_byte_ptr()),
355 PtrMut::new(value_ptr.as_mut_byte_ptr()),
356 );
357 }
358
359 if let Ok(key_shape) = map_def.k().layout.sized_layout() {
365 if key_shape.size() > 0 {
366 unsafe {
367 alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
368 }
369 }
370 }
371 if let Ok(value_shape) = map_def.v().layout.sized_layout() {
372 if value_shape.size() > 0 {
373 unsafe {
374 alloc::alloc::dealloc(
375 value_ptr.as_mut_byte_ptr(),
376 value_shape,
377 );
378 }
379 }
380 }
381
382 *insert_state = MapInsertState::Idle;
384 }
385 }
386 MapInsertState::Idle => {
387 }
389 }
390 }
391 Tracker::Option { building_inner } => {
392 if *building_inner {
394 if let Def::Option(option_def) = parent_frame.shape.def {
395 let init_some_fn = option_def.vtable.init_some_fn;
397
398 let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
400
401 unsafe {
403 init_some_fn(parent_frame.data, inner_value_ptr);
404 }
405
406 if let FrameOwnership::Owned = popped_frame.ownership {
408 if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
409 if layout.size() > 0 {
410 unsafe {
411 alloc::alloc::dealloc(
412 popped_frame.data.as_mut_byte_ptr(),
413 layout,
414 );
415 }
416 }
417 }
418 }
419
420 *building_inner = false;
422 } else {
423 return Err(ReflectError::OperationFailed {
424 shape: parent_frame.shape,
425 operation: "Option frame without Option definition",
426 });
427 }
428 }
429 }
430 Tracker::Uninit | Tracker::Init => {
431 match &parent_frame.shape.def {
434 Def::Pointer(smart_ptr_def) => {
435 let pointee =
436 smart_ptr_def
437 .pointee()
438 .ok_or(ReflectError::InvariantViolation {
439 invariant: "pointer type doesn't have a pointee",
440 })?;
441
442 if !pointee.is_shape(str::SHAPE) {
443 return Err(ReflectError::InvariantViolation {
444 invariant: "only T=str is supported when building SmartPointer<T> and T is unsized",
445 });
446 }
447
448 if !popped_frame.shape.is_shape(String::SHAPE) {
449 return Err(ReflectError::InvariantViolation {
450 invariant: "the popped frame should be String when building a SmartPointer<T>",
451 });
452 }
453
454 popped_frame.require_full_initialization()?;
455
456 use alloc::{rc::Rc, string::String, sync::Arc};
461 let parent_shape = parent_frame.shape;
462
463 let Some(known) = smart_ptr_def.known else {
464 return Err(ReflectError::OperationFailed {
465 shape: parent_shape,
466 operation: "SmartPointerStr for unknown smart pointer kind",
467 });
468 };
469
470 parent_frame.deinit();
471
472 let string_ptr = popped_frame.data.as_mut_byte_ptr() as *mut String;
474 let string_value = unsafe { core::ptr::read(string_ptr) };
475
476 match known {
477 KnownPointer::Box => {
478 let boxed: Box<str> = string_value.into_boxed_str();
479 unsafe {
480 core::ptr::write(
481 parent_frame.data.as_mut_byte_ptr() as *mut Box<str>,
482 boxed,
483 );
484 }
485 }
486 KnownPointer::Arc => {
487 let arc: Arc<str> = Arc::from(string_value.into_boxed_str());
488 unsafe {
489 core::ptr::write(
490 parent_frame.data.as_mut_byte_ptr() as *mut Arc<str>,
491 arc,
492 );
493 }
494 }
495 KnownPointer::Rc => {
496 let rc: Rc<str> = Rc::from(string_value.into_boxed_str());
497 unsafe {
498 core::ptr::write(
499 parent_frame.data.as_mut_byte_ptr() as *mut Rc<str>,
500 rc,
501 );
502 }
503 }
504 _ => {
505 return Err(ReflectError::OperationFailed {
506 shape: parent_shape,
507 operation: "Don't know how to build this pointer type",
508 });
509 }
510 }
511
512 parent_frame.tracker = Tracker::Init;
513
514 popped_frame.tracker = Tracker::Uninit;
515 popped_frame.dealloc();
516 }
517 _ => {
518 unreachable!(
519 "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"
520 )
521 }
522 }
523 }
524 Tracker::SmartPointerSlice {
525 vtable,
526 building_item,
527 } => {
528 if *building_item {
529 let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
531
532 crate::trace!("Pushing element to slice builder");
534 unsafe {
535 let parent_ptr = parent_frame.data.assume_init();
536 (vtable.push_fn)(parent_ptr, element_ptr);
537 }
538
539 popped_frame.tracker = Tracker::Uninit;
540 popped_frame.dealloc();
541
542 if let Tracker::SmartPointerSlice {
543 building_item: bi, ..
544 } = &mut parent_frame.tracker
545 {
546 *bi = false;
547 }
548 }
549 }
550 _ => {}
551 }
552
553 Ok(self)
554 }
555
556 pub fn path(&self) -> String {
559 let mut out = String::new();
560
561 let mut path_components = Vec::new();
562 for (i, frame) in self.frames.iter().enumerate() {
565 match frame.shape.ty {
566 Type::User(user_type) => match user_type {
567 UserType::Struct(struct_type) => {
568 let mut field_str = None;
570 if let Tracker::Struct {
571 current_child: Some(idx),
572 ..
573 } = &frame.tracker
574 {
575 if let Some(field) = struct_type.fields.get(*idx) {
576 field_str = Some(field.name);
577 }
578 }
579 if i == 0 {
580 path_components.push(format!("{}", frame.shape));
582 }
583 if let Some(field_name) = field_str {
584 path_components.push(format!(".{field_name}"));
585 }
586 }
587 UserType::Enum(_enum_type) => {
588 if let Tracker::Enum {
590 variant,
591 current_child,
592 ..
593 } = &frame.tracker
594 {
595 if i == 0 {
596 path_components.push(format!("{}", frame.shape));
598 }
599 path_components.push(format!("::{}", variant.name));
600 if let Some(idx) = *current_child {
601 if let Some(field) = variant.data.fields.get(idx) {
602 path_components.push(format!(".{}", field.name));
603 }
604 }
605 } else if i == 0 {
606 path_components.push(format!("{}", frame.shape));
608 }
609 }
610 UserType::Union(_union_type) => {
611 path_components.push(format!("{}", frame.shape));
612 }
613 UserType::Opaque => {
614 path_components.push("<opaque>".to_string());
615 }
616 },
617 Type::Sequence(seq_type) => match seq_type {
618 facet_core::SequenceType::Array(_array_def) => {
619 if let Tracker::Array {
621 current_child: Some(idx),
622 ..
623 } = &frame.tracker
624 {
625 path_components.push(format!("[{idx}]"));
626 }
627 }
628 _ => {
630 path_components.push("[]".to_string());
632 }
633 },
634 Type::Pointer(_) => {
635 path_components.push("*".to_string());
637 }
638 _ => {
639 }
641 }
642 }
643 for component in path_components {
645 out.push_str(&component);
646 }
647 out
648 }
649}
650
651impl<'facet> Partial<'facet> {
655 pub fn build(&mut self) -> Result<HeapValue<'facet>, ReflectError> {
657 self.require_active()?;
658 if self.frames.len() != 1 {
659 self.state = PartialState::BuildFailed;
660 return Err(ReflectError::InvariantViolation {
661 invariant: "Partial::build() expects a single frame — call end() until that's the case",
662 });
663 }
664
665 let frame = self.frames.pop().unwrap();
666
667 if let Err(e) = frame.require_full_initialization() {
669 self.frames.push(frame);
671 self.state = PartialState::BuildFailed;
672 return Err(e);
673 }
674
675 if let Some(invariants_fn) = frame.shape.vtable.sized().and_then(|v| (v.invariants)()) {
677 let value_ptr = unsafe { frame.data.assume_init().as_const() };
679 let invariants_ok = unsafe { invariants_fn(value_ptr) };
680
681 if !invariants_ok {
682 self.frames.push(frame);
684 self.state = PartialState::BuildFailed;
685 return Err(ReflectError::InvariantViolation {
686 invariant: "Type invariants check failed",
687 });
688 }
689 }
690
691 self.state = PartialState::Built;
693
694 match frame
695 .shape
696 .layout
697 .sized_layout()
698 .map_err(|_layout_err| ReflectError::Unsized {
699 shape: frame.shape,
700 operation: "build (final check for sized layout)",
701 }) {
702 Ok(layout) => Ok(HeapValue {
703 guard: Some(Guard {
704 ptr: frame.data.as_mut_byte_ptr(),
705 layout,
706 }),
707 shape: frame.shape,
708 phantom: PhantomData,
709 }),
710 Err(e) => {
711 self.frames.push(frame);
713 self.state = PartialState::BuildFailed;
714 Err(e)
715 }
716 }
717 }
718}
719
720impl<'facet> Partial<'facet> {
724 pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
730 where
731 U: Facet<'facet>,
732 {
733 self.require_active()?;
734
735 let ptr_const = PtrConst::new(&raw const value);
736 unsafe {
737 self.set_shape(ptr_const, U::SHAPE)?
739 };
740
741 core::mem::forget(value);
743
744 Ok(self)
745 }
746
747 #[inline]
761 pub unsafe fn set_shape(
762 &mut self,
763 src_value: PtrConst<'_>,
764 src_shape: &'static Shape,
765 ) -> Result<&mut Self, ReflectError> {
766 self.require_active()?;
767
768 let fr = self.frames.last_mut().unwrap();
769 crate::trace!("set_shape({src_shape:?})");
770
771 if !fr.shape.is_shape(src_shape) {
772 return Err(ReflectError::WrongShape {
773 expected: fr.shape,
774 actual: src_shape,
775 });
776 }
777
778 fr.deinit();
779
780 unsafe {
783 fr.data.copy_from(src_value, fr.shape).unwrap();
786 }
787
788 unsafe {
790 fr.mark_as_init();
791 }
792
793 Ok(self)
794 }
795
796 pub unsafe fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
806 where
807 F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
808 {
809 self.require_active()?;
810 let frame = self.frames.last_mut().unwrap();
811
812 frame.deinit();
813 f(frame.data)?;
814
815 unsafe {
817 frame.mark_as_init();
818 }
819
820 Ok(self)
821 }
822
823 #[inline]
832 pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
833 let frame = self.frames.last().unwrap();
834
835 let Some(default_fn) = (frame.shape.vtable.sized().unwrap().default_in_place)() else {
836 return Err(ReflectError::OperationFailed {
837 shape: frame.shape,
838 operation: "type does not implement Default",
839 });
840 };
841
842 unsafe {
845 self.set_from_function(move |ptr| {
846 default_fn(ptr);
847 Ok(())
848 })
849 }
850 }
851
852 pub unsafe fn set_from_peek(&mut self, peek: &Peek<'_, '_>) -> Result<&mut Self, ReflectError> {
863 self.require_active()?;
864
865 let src_ptr = peek
867 .data()
868 .thin()
869 .expect("set_from_peek requires thin pointers");
870 let src_shape = peek.shape();
871
872 unsafe { self.set_shape(src_ptr, src_shape) }
874 }
875
876 pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
880 self.require_active()?;
881
882 let frame = self.frames.last_mut().unwrap();
883
884 let Some(parse_fn) = (frame.shape.vtable.sized().unwrap().parse)() else {
886 return Err(ReflectError::OperationFailed {
887 shape: frame.shape,
888 operation: "Type does not support parsing from string",
889 });
890 };
891
892 frame.deinit();
894
895 let result = unsafe { parse_fn(s, frame.data) };
897 if let Err(_pe) = result {
898 return Err(ReflectError::OperationFailed {
900 shape: frame.shape,
901 operation: "Failed to parse string value",
902 });
903 }
904
905 unsafe {
907 frame.mark_as_init();
908 }
909 Ok(self)
910 }
911}
912
913impl<'facet> Partial<'facet> {
917 pub fn selected_variant(&self) -> Option<Variant> {
919 let frame = self.frames.last()?;
920
921 match &frame.tracker {
922 Tracker::Enum { variant, .. } => Some(**variant),
923 _ => None,
924 }
925 }
926
927 pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'static Variant)> {
929 let frame = self.frames.last()?;
930
931 if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
932 enum_def
933 .variants
934 .iter()
935 .enumerate()
936 .find(|(_, v)| v.name == variant_name)
937 } else {
938 None
939 }
940 }
941
942 pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
958 self.require_active()?;
959
960 let frame = self.frames.last().unwrap();
961 let enum_type = frame.get_enum_type()?;
962
963 if index >= enum_type.variants.len() {
964 return Err(ReflectError::OperationFailed {
965 shape: frame.shape,
966 operation: "variant index out of bounds",
967 });
968 }
969 let variant = &enum_type.variants[index];
970
971 self.select_variant_internal(&enum_type, variant)?;
972 Ok(self)
973 }
974
975 pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
979 self.require_active()?;
980
981 let frame = self.frames.last_mut().unwrap();
982 let enum_type = frame.get_enum_type()?;
983
984 let Some(variant) = enum_type.variants.iter().find(|v| v.name == variant_name) else {
985 return Err(ReflectError::OperationFailed {
986 shape: frame.shape,
987 operation: "No variant found with the given name",
988 });
989 };
990
991 self.select_variant_internal(&enum_type, variant)?;
992 Ok(self)
993 }
994
995 pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
1000 self.require_active()?;
1001
1002 let frame = self.frames.last().unwrap();
1004
1005 let enum_type = match frame.shape.ty {
1007 Type::User(UserType::Enum(e)) => e,
1008 _ => {
1009 return Err(ReflectError::WasNotA {
1010 expected: "enum",
1011 actual: frame.shape,
1012 });
1013 }
1014 };
1015
1016 let Some(variant) = enum_type
1018 .variants
1019 .iter()
1020 .find(|v| v.discriminant == Some(discriminant))
1021 else {
1022 return Err(ReflectError::OperationFailed {
1023 shape: frame.shape,
1024 operation: "No variant found with the given discriminant",
1025 });
1026 };
1027
1028 self.select_variant_internal(&enum_type, variant)?;
1030
1031 Ok(self)
1032 }
1033}
1034
1035impl Partial<'_> {
1039 pub fn field_index(&self, field_name: &str) -> Option<usize> {
1044 let frame = self.frames.last()?;
1045
1046 match frame.shape.ty {
1047 Type::User(UserType::Struct(struct_def)) => {
1048 struct_def.fields.iter().position(|f| f.name == field_name)
1049 }
1050 Type::User(UserType::Enum(_)) => {
1051 if let Tracker::Enum { variant, .. } = &frame.tracker {
1053 variant
1054 .data
1055 .fields
1056 .iter()
1057 .position(|f| f.name == field_name)
1058 } else {
1059 None
1060 }
1061 }
1062 _ => None,
1063 }
1064 }
1065
1066 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
1068 let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
1069
1070 match &frame.tracker {
1071 Tracker::Uninit => Ok(false),
1072 Tracker::Init => Ok(true),
1073 Tracker::Struct { iset, .. } => Ok(iset.get(index)),
1074 Tracker::Enum { data, variant, .. } => {
1075 if data.get(index) {
1077 return Ok(true);
1078 }
1079
1080 if let Some(field) = variant.data.fields.get(index) {
1082 if let Type::User(UserType::Struct(field_struct)) = field.shape.ty {
1083 if field_struct.fields.is_empty() {
1084 return Ok(true);
1085 }
1086 }
1087 }
1088
1089 Ok(false)
1090 }
1091 Tracker::Option { building_inner } => {
1092 if index == 0 {
1094 Ok(!building_inner)
1095 } else {
1096 Err(ReflectError::InvalidOperation {
1097 operation: "is_field_set",
1098 reason: "Option only has one field (index 0)",
1099 })
1100 }
1101 }
1102 _ => Err(ReflectError::InvalidOperation {
1103 operation: "is_field_set",
1104 reason: "Current frame is not a struct, enum variant, or option",
1105 }),
1106 }
1107 }
1108
1109 pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
1114 self.require_active()?;
1115
1116 let frame = self.frames.last().unwrap();
1117 let fields = self.get_fields()?;
1118 let Some(idx) = fields.iter().position(|f| f.name == field_name) else {
1119 return Err(ReflectError::FieldError {
1120 shape: frame.shape,
1121 field_error: facet_core::FieldError::NoSuchField,
1122 });
1123 };
1124 self.begin_nth_field(idx)
1125 }
1126
1127 pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1131 self.require_active()?;
1132 let frame = self.frames.last_mut().unwrap();
1133
1134 let next_frame = match frame.shape.ty {
1135 Type::User(user_type) => match user_type {
1136 UserType::Struct(struct_type) => {
1137 Self::begin_nth_struct_field(frame, struct_type, idx)?
1138 }
1139 UserType::Enum(_) => {
1140 match &frame.tracker {
1142 Tracker::Enum { variant, .. } => {
1143 Self::begin_nth_enum_field(frame, variant, idx)?
1144 }
1145 _ => {
1146 return Err(ReflectError::OperationFailed {
1147 shape: frame.shape,
1148 operation: "must call select_variant before selecting enum fields",
1149 });
1150 }
1151 }
1152 }
1153 UserType::Union(_) => {
1154 return Err(ReflectError::OperationFailed {
1155 shape: frame.shape,
1156 operation: "cannot select a field from a union",
1157 });
1158 }
1159 UserType::Opaque => {
1160 return Err(ReflectError::OperationFailed {
1161 shape: frame.shape,
1162 operation: "cannot select a field from an opaque type",
1163 });
1164 }
1165 },
1166 Type::Sequence(sequence_type) => match sequence_type {
1167 SequenceType::Array(array_type) => {
1168 Self::begin_nth_array_element(frame, array_type, idx)?
1169 }
1170 SequenceType::Slice(_) => {
1171 return Err(ReflectError::OperationFailed {
1172 shape: frame.shape,
1173 operation: "cannot select a field from slices yet",
1174 });
1175 }
1176 },
1177 _ => {
1178 return Err(ReflectError::OperationFailed {
1179 shape: frame.shape,
1180 operation: "cannot select a field from this type",
1181 });
1182 }
1183 };
1184
1185 self.frames.push(next_frame);
1186 Ok(self)
1187 }
1188
1189 pub fn set_nth_field_to_default(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1198 self.require_active()?;
1199
1200 let frame = self.frames.last().unwrap();
1201 let fields = self.get_fields()?;
1202
1203 if idx >= fields.len() {
1204 return Err(ReflectError::OperationFailed {
1205 shape: frame.shape,
1206 operation: "field index out of bounds",
1207 });
1208 }
1209
1210 let field = fields[idx];
1211
1212 if let Some(field_default_fn) = field.vtable.default_fn {
1214 self.begin_nth_field(idx)?;
1215 unsafe {
1217 self.set_from_function(|ptr| {
1218 field_default_fn(ptr);
1219 Ok(())
1220 })?;
1221 }
1222 self.end()
1223 } else if field.shape().is(Characteristic::Default) {
1224 self.begin_nth_field(idx)?;
1225 self.set_default()?;
1226 self.end()
1227 } else {
1228 return Err(ReflectError::DefaultAttrButNoDefaultImpl {
1229 shape: field.shape(),
1230 });
1231 }
1232 }
1233
1234 pub fn steal_nth_field(
1238 &mut self,
1239 src: &mut Partial,
1240 field_index: usize,
1241 ) -> Result<&mut Self, ReflectError> {
1242 let dst_shape = self.shape();
1243 let src_shape = src.shape();
1244 if dst_shape != src_shape {
1245 return Err(ReflectError::HeistCancelledDifferentShapes {
1246 src_shape,
1247 dst_shape,
1248 });
1249 }
1250
1251 if !src.is_field_set(field_index)? {
1254 return Err(ReflectError::InvariantViolation {
1255 invariant: "stolen field must be initialized",
1256 });
1257 }
1258
1259 let maybe_fields = match src_shape.ty {
1260 Type::Primitive(_primitive_type) => None,
1261 Type::Sequence(_sequence_type) => None,
1262 Type::User(user_type) => match user_type {
1263 UserType::Struct(struct_type) => Some(struct_type.fields),
1264 UserType::Enum(_enum_type) => match self.selected_variant() {
1265 Some(variant) => Some(variant.data.fields),
1266 None => {
1267 return Err(ReflectError::InvariantViolation {
1268 invariant: "enum field thief must have variant selected",
1269 });
1270 }
1271 },
1272 UserType::Union(_union_type) => None,
1273 UserType::Opaque => None,
1274 },
1275 Type::Pointer(_pointer_type) => None,
1276 };
1277
1278 let Some(fields) = maybe_fields else {
1279 return Err(ReflectError::OperationFailed {
1280 shape: src_shape,
1281 operation: "fetching field list for steal_nth_field",
1282 });
1283 };
1284
1285 if field_index >= fields.len() {
1286 return Err(ReflectError::OperationFailed {
1287 shape: src_shape,
1288 operation: "field index out of bounds",
1289 });
1290 }
1291 let field = fields[field_index];
1292
1293 let src_frame = src.frames.last_mut().unwrap();
1294
1295 self.begin_nth_field(field_index)?;
1296 unsafe {
1297 self.set_from_function(|dst_field_ptr| {
1298 let src_field_ptr = src_frame.data.field_init_at(field.offset).as_const();
1299 dst_field_ptr.copy_from(src_field_ptr, field.shape).unwrap();
1300 Ok(())
1301 })?;
1302 }
1303 self.end()?;
1304
1305 match &mut src_frame.tracker {
1307 Tracker::Uninit => {
1308 unreachable!("we just stole a field from src, it couldn't have been fully uninit")
1309 }
1310 Tracker::Init => {
1311 let mut iset = ISet::new(fields.len());
1314 iset.set_all();
1315 iset.unset(field_index);
1316 src_frame.tracker = Tracker::Struct {
1317 iset,
1318 current_child: None,
1319 }
1320 }
1321 Tracker::Array { .. } => unreachable!("can't steal fields from arrays"),
1322 Tracker::Struct { iset, .. } => {
1323 iset.unset(field_index);
1324 }
1325 Tracker::SmartPointer { .. } => {
1326 unreachable!("can't steal fields from smart pointers")
1327 }
1328 Tracker::SmartPointerSlice { .. } => {
1329 unreachable!("can't steal fields from smart pointer slices")
1330 }
1331 Tracker::Enum { data, .. } => {
1332 data.unset(field_index);
1333 }
1334 Tracker::List { .. } => {
1335 unreachable!("can't steal fields from lists")
1336 }
1337 Tracker::Map { .. } => {
1338 unreachable!("can't steal fields from maps")
1339 }
1340 Tracker::Option { .. } => {
1341 unreachable!("can't steal fields from options")
1342 }
1343 }
1344
1345 Ok(self)
1346 }
1347}
1348
1349impl Partial<'_> {
1353 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
1355 crate::trace!("begin_smart_ptr()");
1356 self.require_active()?;
1357 let frame = self.frames.last_mut().unwrap();
1358
1359 match &frame.shape.def {
1361 Def::Pointer(smart_ptr_def) => {
1362 match smart_ptr_def.known {
1364 Some(KnownPointer::Box)
1365 | Some(KnownPointer::Rc)
1366 | Some(KnownPointer::Arc)
1367 | Some(KnownPointer::SharedReference) => {
1368 }
1370 _ => {
1371 return Err(ReflectError::OperationFailed {
1372 shape: frame.shape,
1373 operation: "only the following pointers are currently supported: Box<T>, Rc<T>, Arc<T>, and &T",
1374 });
1375 }
1376 }
1377
1378 let pointee_shape = match smart_ptr_def.pointee() {
1380 Some(shape) => shape,
1381 None => {
1382 return Err(ReflectError::OperationFailed {
1383 shape: frame.shape,
1384 operation: "Box must have a pointee shape",
1385 });
1386 }
1387 };
1388
1389 if pointee_shape.layout.sized_layout().is_ok() {
1390 if matches!(frame.tracker, Tracker::Uninit) {
1394 frame.tracker = Tracker::SmartPointer {
1395 is_initialized: false,
1396 };
1397 }
1398
1399 let inner_layout = match pointee_shape.layout.sized_layout() {
1400 Ok(layout) => layout,
1401 Err(_) => {
1402 return Err(ReflectError::Unsized {
1403 shape: pointee_shape,
1404 operation: "begin_smart_ptr, calculating inner value layout",
1405 });
1406 }
1407 };
1408 let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1409 if inner_ptr.is_null() {
1410 return Err(ReflectError::OperationFailed {
1411 shape: frame.shape,
1412 operation: "failed to allocate memory for smart pointer inner value",
1413 });
1414 }
1415
1416 self.frames.push(Frame::new(
1418 PtrUninit::new(inner_ptr),
1419 pointee_shape,
1420 FrameOwnership::Owned,
1421 ));
1422 } else {
1423 if pointee_shape == str::SHAPE {
1425 crate::trace!("Pointee is str");
1426
1427 let string_layout = String::SHAPE
1429 .layout
1430 .sized_layout()
1431 .expect("String must have a sized layout");
1432 let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1433 if string_ptr.is_null() {
1434 alloc::alloc::handle_alloc_error(string_layout);
1435 }
1436 let mut frame = Frame::new(
1437 PtrUninit::new(string_ptr),
1438 String::SHAPE,
1439 FrameOwnership::Owned,
1440 );
1441 frame.tracker = Tracker::Uninit;
1442 self.frames.push(frame);
1443 } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1444 crate::trace!("Pointee is [{}]", _st.t);
1445
1446 let slice_builder_vtable = smart_ptr_def
1448 .vtable
1449 .slice_builder_vtable
1450 .ok_or(ReflectError::OperationFailed {
1451 shape: frame.shape,
1452 operation: "smart pointer does not support slice building",
1453 })?;
1454
1455 let builder_ptr = (slice_builder_vtable.new_fn)();
1457
1458 if let FrameOwnership::Owned = frame.ownership {
1460 if let Ok(layout) = frame.shape.layout.sized_layout() {
1461 if layout.size() > 0 {
1462 unsafe {
1463 alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1464 };
1465 }
1466 }
1467 }
1468
1469 frame.data = PtrUninit::new(builder_ptr.as_mut_byte_ptr());
1471 frame.tracker = Tracker::SmartPointerSlice {
1472 vtable: slice_builder_vtable,
1473 building_item: false,
1474 };
1475 frame.ownership = FrameOwnership::ManagedElsewhere;
1477 } else {
1478 todo!("unsupported unsize pointee shape: {}", pointee_shape)
1479 }
1480 }
1481
1482 Ok(self)
1483 }
1484 _ => Err(ReflectError::OperationFailed {
1485 shape: frame.shape,
1486 operation: "push_smart_ptr can only be called on compatible types",
1487 }),
1488 }
1489 }
1490}
1491
1492impl Partial<'_> {
1496 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1504 crate::trace!("begin_list()");
1505 self.require_active()?;
1506 let frame = self.frames.last_mut().unwrap();
1507
1508 match &frame.tracker {
1509 Tracker::Uninit => {
1510 }
1512 Tracker::Init => {
1513 frame.tracker = Tracker::List {
1515 is_initialized: true,
1516 current_child: false,
1517 };
1518 return Ok(self);
1519 }
1520 Tracker::List { is_initialized, .. } => {
1521 if *is_initialized {
1522 return Ok(self);
1524 }
1525 }
1526 Tracker::SmartPointerSlice { .. } => {
1527 return Ok(self);
1529 }
1530 _ => {
1531 return Err(ReflectError::UnexpectedTracker {
1532 message: "begin_list called but tracker isn't something list-like",
1533 current_tracker: frame.tracker.kind(),
1534 });
1535 }
1536 };
1537
1538 let list_def = match &frame.shape.def {
1540 Def::List(list_def) => list_def,
1541 _ => {
1542 return Err(ReflectError::OperationFailed {
1543 shape: frame.shape,
1544 operation: "begin_list can only be called on List types",
1545 });
1546 }
1547 };
1548
1549 let init_fn = match list_def.vtable.init_in_place_with_capacity {
1551 Some(f) => f,
1552 None => {
1553 return Err(ReflectError::OperationFailed {
1554 shape: frame.shape,
1555 operation: "list type does not support initialization with capacity",
1556 });
1557 }
1558 };
1559
1560 unsafe {
1562 init_fn(frame.data, 0);
1563 }
1564
1565 frame.tracker = Tracker::List {
1567 is_initialized: true,
1568 current_child: false,
1569 };
1570
1571 Ok(self)
1572 }
1573
1574 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1577 crate::trace!("begin_list_item()");
1578 self.require_active()?;
1579 let frame = self.frames.last_mut().unwrap();
1580
1581 if let Tracker::SmartPointerSlice {
1583 building_item,
1584 vtable: _,
1585 } = &frame.tracker
1586 {
1587 if *building_item {
1588 return Err(ReflectError::OperationFailed {
1589 shape: frame.shape,
1590 operation: "already building an item, call end() first",
1591 });
1592 }
1593
1594 let element_shape = match &frame.shape.def {
1596 Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1597 Some(pointee_shape) => match &pointee_shape.ty {
1598 Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1599 _ => {
1600 return Err(ReflectError::OperationFailed {
1601 shape: frame.shape,
1602 operation: "smart pointer pointee is not a slice",
1603 });
1604 }
1605 },
1606 None => {
1607 return Err(ReflectError::OperationFailed {
1608 shape: frame.shape,
1609 operation: "smart pointer has no pointee",
1610 });
1611 }
1612 },
1613 _ => {
1614 return Err(ReflectError::OperationFailed {
1615 shape: frame.shape,
1616 operation: "expected smart pointer definition",
1617 });
1618 }
1619 };
1620
1621 crate::trace!("Pointee is a slice of {element_shape}");
1623 let element_layout = match element_shape.layout.sized_layout() {
1624 Ok(layout) => layout,
1625 Err(_) => {
1626 return Err(ReflectError::OperationFailed {
1627 shape: element_shape,
1628 operation: "cannot allocate unsized element",
1629 });
1630 }
1631 };
1632
1633 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1634 if element_ptr.is_null() {
1635 alloc::alloc::handle_alloc_error(element_layout);
1636 }
1637
1638 crate::trace!("Pushing element frame, which we just allocated");
1640 let element_frame = Frame::new(
1641 PtrUninit::new(element_ptr),
1642 element_shape,
1643 FrameOwnership::Owned,
1644 );
1645 self.frames.push(element_frame);
1646
1647 let parent_idx = self.frames.len() - 2;
1650 if let Tracker::SmartPointerSlice { building_item, .. } =
1651 &mut self.frames[parent_idx].tracker
1652 {
1653 crate::trace!("Marking element frame as building item");
1654 *building_item = true;
1655 }
1656
1657 return Ok(self);
1658 }
1659
1660 let list_def = match &frame.shape.def {
1662 Def::List(list_def) => list_def,
1663 _ => {
1664 return Err(ReflectError::OperationFailed {
1665 shape: frame.shape,
1666 operation: "push can only be called on List types",
1667 });
1668 }
1669 };
1670
1671 match &mut frame.tracker {
1673 Tracker::List {
1674 is_initialized: true,
1675 current_child,
1676 } => {
1677 if *current_child {
1678 return Err(ReflectError::OperationFailed {
1679 shape: frame.shape,
1680 operation: "already pushing an element, call pop() first",
1681 });
1682 }
1683 *current_child = true;
1684 }
1685 _ => {
1686 return Err(ReflectError::OperationFailed {
1687 shape: frame.shape,
1688 operation: "must call begin_list() before push()",
1689 });
1690 }
1691 }
1692
1693 let element_shape = list_def.t();
1695
1696 let element_layout = match element_shape.layout.sized_layout() {
1698 Ok(layout) => layout,
1699 Err(_) => {
1700 return Err(ReflectError::Unsized {
1701 shape: element_shape,
1702 operation: "begin_list_item: calculating element layout",
1703 });
1704 }
1705 };
1706 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1707
1708 if element_ptr.is_null() {
1709 return Err(ReflectError::OperationFailed {
1710 shape: frame.shape,
1711 operation: "failed to allocate memory for list element",
1712 });
1713 }
1714
1715 self.frames.push(Frame::new(
1717 PtrUninit::new(element_ptr),
1718 element_shape,
1719 FrameOwnership::Owned,
1720 ));
1721
1722 Ok(self)
1723 }
1724}
1725
1726impl Partial<'_> {
1730 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1735 self.require_active()?;
1736 let frame = self.frames.last_mut().unwrap();
1737
1738 let map_def = match &frame.shape.def {
1740 Def::Map(map_def) => map_def,
1741 _ => {
1742 return Err(ReflectError::OperationFailed {
1743 shape: frame.shape,
1744 operation: "begin_map can only be called on Map types",
1745 });
1746 }
1747 };
1748
1749 let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1750
1751 unsafe {
1753 init_fn(frame.data, 0);
1754 }
1755
1756 frame.tracker = Tracker::Map {
1758 is_initialized: true,
1759 insert_state: MapInsertState::Idle,
1760 };
1761
1762 Ok(self)
1763 }
1764
1765 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1769 self.require_active()?;
1770 let frame = self.frames.last_mut().unwrap();
1771
1772 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1774 (
1775 Def::Map(map_def),
1776 Tracker::Map {
1777 is_initialized: true,
1778 insert_state,
1779 },
1780 ) => {
1781 match insert_state {
1782 MapInsertState::Idle => {
1783 *insert_state = MapInsertState::PushingKey { key_ptr: None };
1785 }
1786 MapInsertState::PushingKey { key_ptr } => {
1787 if key_ptr.is_some() {
1788 return Err(ReflectError::OperationFailed {
1789 shape: frame.shape,
1790 operation: "already pushing a key, call end() first",
1791 });
1792 }
1793 }
1794 _ => {
1795 return Err(ReflectError::OperationFailed {
1796 shape: frame.shape,
1797 operation: "must complete current operation before begin_key()",
1798 });
1799 }
1800 }
1801 map_def
1802 }
1803 _ => {
1804 return Err(ReflectError::OperationFailed {
1805 shape: frame.shape,
1806 operation: "must call begin_map() before begin_key()",
1807 });
1808 }
1809 };
1810
1811 let key_shape = map_def.k();
1813
1814 let key_layout = match key_shape.layout.sized_layout() {
1816 Ok(layout) => layout,
1817 Err(_) => {
1818 return Err(ReflectError::Unsized {
1819 shape: key_shape,
1820 operation: "begin_key allocating key",
1821 });
1822 }
1823 };
1824 let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1825 if key_ptr_raw.is_null() {
1826 return Err(ReflectError::OperationFailed {
1827 shape: frame.shape,
1828 operation: "failed to allocate memory for map key",
1829 });
1830 }
1831
1832 match &mut frame.tracker {
1834 Tracker::Map {
1835 insert_state: MapInsertState::PushingKey { key_ptr: kp },
1836 ..
1837 } => {
1838 *kp = Some(PtrUninit::new(key_ptr_raw));
1839 }
1840 _ => unreachable!(),
1841 }
1842
1843 self.frames.push(Frame::new(
1845 PtrUninit::new(key_ptr_raw),
1846 key_shape,
1847 FrameOwnership::ManagedElsewhere, ));
1849
1850 Ok(self)
1851 }
1852
1853 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1856 self.require_active()?;
1857 let frame = self.frames.last_mut().unwrap();
1858
1859 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1861 (
1862 Def::Map(map_def),
1863 Tracker::Map {
1864 insert_state: MapInsertState::PushingValue { value_ptr, .. },
1865 ..
1866 },
1867 ) => {
1868 if value_ptr.is_some() {
1869 return Err(ReflectError::OperationFailed {
1870 shape: frame.shape,
1871 operation: "already pushing a value, call pop() first",
1872 });
1873 }
1874 map_def
1875 }
1876 _ => {
1877 return Err(ReflectError::OperationFailed {
1878 shape: frame.shape,
1879 operation: "must complete key before push_value()",
1880 });
1881 }
1882 };
1883
1884 let value_shape = map_def.v();
1886
1887 let value_layout = match value_shape.layout.sized_layout() {
1889 Ok(layout) => layout,
1890 Err(_) => {
1891 return Err(ReflectError::Unsized {
1892 shape: value_shape,
1893 operation: "begin_value allocating value",
1894 });
1895 }
1896 };
1897 let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1898
1899 if value_ptr_raw.is_null() {
1900 return Err(ReflectError::OperationFailed {
1901 shape: frame.shape,
1902 operation: "failed to allocate memory for map value",
1903 });
1904 }
1905
1906 match &mut frame.tracker {
1908 Tracker::Map {
1909 insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1910 ..
1911 } => {
1912 *vp = Some(PtrUninit::new(value_ptr_raw));
1913 }
1914 _ => unreachable!(),
1915 }
1916
1917 self.frames.push(Frame::new(
1919 PtrUninit::new(value_ptr_raw),
1920 value_shape,
1921 FrameOwnership::ManagedElsewhere, ));
1923
1924 Ok(self)
1925 }
1926}
1927
1928impl Partial<'_> {
1932 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
1934 self.require_active()?;
1935 let frame = self.frames.last_mut().unwrap();
1936
1937 let option_def = match frame.shape.def {
1939 Def::Option(def) => def,
1940 _ => {
1941 return Err(ReflectError::WasNotA {
1942 expected: "Option",
1943 actual: frame.shape,
1944 });
1945 }
1946 };
1947
1948 if matches!(frame.tracker, Tracker::Uninit) {
1950 frame.tracker = Tracker::Option {
1951 building_inner: true,
1952 };
1953 }
1954
1955 let inner_shape = option_def.t;
1957
1958 let inner_layout =
1960 inner_shape
1961 .layout
1962 .sized_layout()
1963 .map_err(|_| ReflectError::Unsized {
1964 shape: inner_shape,
1965 operation: "begin_some, allocating Option inner value",
1966 })?;
1967
1968 let inner_data = if inner_layout.size() == 0 {
1969 PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
1971 } else {
1972 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
1974 if ptr.is_null() {
1975 alloc::alloc::handle_alloc_error(inner_layout);
1976 }
1977 PtrUninit::new(ptr)
1978 };
1979
1980 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
1982 self.frames.push(inner_frame);
1983
1984 Ok(self)
1985 }
1986
1987 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
1989 self.require_active()?;
1990
1991 let (inner_shape, has_try_from, parent_shape) = {
1993 let frame = self.frames.last().unwrap();
1994 if let Some(inner_fn) = frame.shape.inner {
1995 let inner_shape = inner_fn();
1996 let has_try_from = frame
1997 .shape
1998 .vtable
1999 .sized()
2000 .and_then(|v| (v.try_from)())
2001 .is_some();
2002 (Some(inner_shape), has_try_from, frame.shape)
2003 } else {
2004 (None, false, frame.shape)
2005 }
2006 };
2007
2008 if let Some(inner_shape) = inner_shape {
2009 if has_try_from {
2010 let inner_layout =
2017 inner_shape
2018 .layout
2019 .sized_layout()
2020 .map_err(|_| ReflectError::Unsized {
2021 shape: inner_shape,
2022 operation: "begin_inner, getting inner layout",
2023 })?;
2024
2025 let inner_data = if inner_layout.size() == 0 {
2026 PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2028 } else {
2029 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2031 if ptr.is_null() {
2032 alloc::alloc::handle_alloc_error(inner_layout);
2033 }
2034 PtrUninit::new(ptr)
2035 };
2036
2037 trace!(
2041 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
2042 );
2043 self.frames
2044 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2045
2046 Ok(self)
2047 } else {
2048 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
2051 self.begin_nth_field(0)
2052 }
2053 } else {
2054 Err(ReflectError::OperationFailed {
2055 shape: parent_shape,
2056 operation: "type does not have an inner value",
2057 })
2058 }
2059 }
2060}
2061
2062impl<'facet> Partial<'facet> {
2066 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2070 where
2071 U: Facet<'facet>,
2072 {
2073 self.begin_nth_field(idx)?.set(value)?.end()
2074 }
2075
2076 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
2078 where
2079 U: Facet<'facet>,
2080 {
2081 self.begin_field(field_name)?.set(value)?.end()
2082 }
2083
2084 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2086 where
2087 U: Facet<'facet>,
2088 {
2089 self.begin_key()?.set(value)?.end()
2090 }
2091
2092 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2094 where
2095 U: Facet<'facet>,
2096 {
2097 self.begin_value()?.set(value)?.end()
2098 }
2099
2100 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2102 where
2103 U: Facet<'facet>,
2104 {
2105 self.begin_list_item()?.set(value)?.end()
2106 }
2107}
2108
2109impl<'facet> Partial<'facet> {
2113 fn select_variant_internal(
2122 &mut self,
2123 enum_type: &EnumType,
2124 variant: &'static Variant,
2125 ) -> Result<(), ReflectError> {
2126 let frame = self.frames.last().unwrap();
2128
2129 match enum_type.enum_repr {
2131 EnumRepr::RustNPO => {
2132 return Err(ReflectError::OperationFailed {
2133 shape: frame.shape,
2134 operation: "RustNPO enums are not supported for incremental building",
2135 });
2136 }
2137 EnumRepr::U8
2138 | EnumRepr::U16
2139 | EnumRepr::U32
2140 | EnumRepr::U64
2141 | EnumRepr::I8
2142 | EnumRepr::I16
2143 | EnumRepr::I32
2144 | EnumRepr::I64
2145 | EnumRepr::USize
2146 | EnumRepr::ISize => {
2147 }
2149 }
2150
2151 let Some(discriminant) = variant.discriminant else {
2152 return Err(ReflectError::OperationFailed {
2153 shape: frame.shape,
2154 operation: "trying to select an enum variant without a discriminant",
2155 });
2156 };
2157
2158 let fr = self.frames.last_mut().unwrap();
2160
2161 unsafe {
2163 match enum_type.enum_repr {
2164 EnumRepr::U8 => {
2165 let ptr = fr.data.as_mut_byte_ptr();
2166 *ptr = discriminant as u8;
2167 }
2168 EnumRepr::U16 => {
2169 let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
2170 *ptr = discriminant as u16;
2171 }
2172 EnumRepr::U32 => {
2173 let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
2174 *ptr = discriminant as u32;
2175 }
2176 EnumRepr::U64 => {
2177 let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
2178 *ptr = discriminant as u64;
2179 }
2180 EnumRepr::I8 => {
2181 let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
2182 *ptr = discriminant as i8;
2183 }
2184 EnumRepr::I16 => {
2185 let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
2186 *ptr = discriminant as i16;
2187 }
2188 EnumRepr::I32 => {
2189 let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
2190 *ptr = discriminant as i32;
2191 }
2192 EnumRepr::I64 => {
2193 let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
2194 *ptr = discriminant;
2195 }
2196 EnumRepr::USize => {
2197 let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
2198 *ptr = discriminant as usize;
2199 }
2200 EnumRepr::ISize => {
2201 let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
2202 *ptr = discriminant as isize;
2203 }
2204 _ => unreachable!("Already checked enum representation above"),
2205 }
2206 }
2207
2208 fr.tracker = Tracker::Enum {
2210 variant,
2211 data: ISet::new(variant.data.fields.len()),
2212 current_child: None,
2213 };
2214
2215 Ok(())
2216 }
2217
2218 fn get_fields(&self) -> Result<&'static [Field], ReflectError> {
2221 let frame = self.frames.last().unwrap();
2222 match frame.shape.ty {
2223 Type::Primitive(_) => Err(ReflectError::OperationFailed {
2224 shape: frame.shape,
2225 operation: "cannot select a field from a primitive type",
2226 }),
2227 Type::Sequence(_) => Err(ReflectError::OperationFailed {
2228 shape: frame.shape,
2229 operation: "cannot select a field from a sequence type",
2230 }),
2231 Type::User(user_type) => match user_type {
2232 UserType::Struct(struct_type) => Ok(struct_type.fields),
2233 UserType::Enum(_) => {
2234 let Tracker::Enum { variant, .. } = &frame.tracker else {
2235 return Err(ReflectError::OperationFailed {
2236 shape: frame.shape,
2237 operation: "must select variant before selecting enum fields",
2238 });
2239 };
2240 Ok(variant.data.fields)
2241 }
2242 UserType::Union(_) => Err(ReflectError::OperationFailed {
2243 shape: frame.shape,
2244 operation: "cannot select a field from a union type",
2245 }),
2246 UserType::Opaque => Err(ReflectError::OperationFailed {
2247 shape: frame.shape,
2248 operation: "opaque types cannot be reflected upon",
2249 }),
2250 },
2251 Type::Pointer(_) => Err(ReflectError::OperationFailed {
2252 shape: frame.shape,
2253 operation: "cannot select a field from a pointer type",
2254 }),
2255 }
2256 }
2257
2258 fn begin_nth_struct_field(
2260 frame: &mut Frame,
2261 struct_type: StructType,
2262 idx: usize,
2263 ) -> Result<Frame, ReflectError> {
2264 if idx >= struct_type.fields.len() {
2265 return Err(ReflectError::OperationFailed {
2266 shape: frame.shape,
2267 operation: "field index out of bounds",
2268 });
2269 }
2270 let field = &struct_type.fields[idx];
2271
2272 if !matches!(frame.tracker, Tracker::Struct { .. }) {
2273 frame.tracker = Tracker::Struct {
2274 iset: ISet::new(struct_type.fields.len()),
2275 current_child: None,
2276 }
2277 }
2278
2279 let was_field_init = match &mut frame.tracker {
2280 Tracker::Struct {
2281 iset,
2282 current_child,
2283 } => {
2284 *current_child = Some(idx);
2285 iset.get(idx)
2286 }
2287 _ => unreachable!(),
2288 };
2289
2290 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2292 let field_shape = field.shape;
2293
2294 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2295 if was_field_init {
2296 unsafe {
2297 next_frame.mark_as_init();
2299 }
2300 }
2301
2302 Ok(next_frame)
2303 }
2304
2305 fn begin_nth_array_element(
2307 frame: &mut Frame,
2308 array_type: ArrayType,
2309 idx: usize,
2310 ) -> Result<Frame, ReflectError> {
2311 if idx >= array_type.n {
2312 return Err(ReflectError::OperationFailed {
2313 shape: frame.shape,
2314 operation: "array index out of bounds",
2315 });
2316 }
2317
2318 if array_type.n > 63 {
2319 return Err(ReflectError::OperationFailed {
2320 shape: frame.shape,
2321 operation: "arrays larger than 63 elements are not yet supported",
2322 });
2323 }
2324
2325 match &frame.tracker {
2327 Tracker::Uninit => {
2328 frame.tracker = Tracker::Array {
2330 iset: ISet::default(),
2331 current_child: None,
2332 };
2333 }
2334 Tracker::Array { .. } => {
2335 }
2337 _other => {
2338 return Err(ReflectError::OperationFailed {
2339 shape: frame.shape,
2340 operation: "unexpected tracker state: expected Uninit or Array",
2341 });
2342 }
2343 }
2344
2345 match &mut frame.tracker {
2346 Tracker::Array {
2347 iset,
2348 current_child,
2349 } => {
2350 *current_child = Some(idx);
2351 let was_field_init = iset.get(idx);
2352
2353 let Ok(element_layout) = array_type.t.layout.sized_layout() else {
2355 return Err(ReflectError::Unsized {
2356 shape: array_type.t,
2357 operation: "begin_nth_element, calculating array element offset",
2358 });
2359 };
2360 let offset = element_layout.size() * idx;
2361 let element_data = unsafe { frame.data.field_uninit_at(offset) };
2362
2363 let mut next_frame = Frame::new(element_data, array_type.t, FrameOwnership::Field);
2364 if was_field_init {
2365 unsafe {
2367 next_frame.mark_as_init();
2368 }
2369 }
2370 Ok(next_frame)
2371 }
2372 _ => unreachable!(),
2373 }
2374 }
2375
2376 fn begin_nth_enum_field(
2378 frame: &mut Frame,
2379 variant: &'static Variant,
2380 idx: usize,
2381 ) -> Result<Frame, ReflectError> {
2382 if idx >= variant.data.fields.len() {
2383 return Err(ReflectError::OperationFailed {
2384 shape: frame.shape,
2385 operation: "enum field index out of bounds",
2386 });
2387 }
2388
2389 let field = &variant.data.fields[idx];
2390
2391 let was_field_init = match &mut frame.tracker {
2393 Tracker::Enum {
2394 data,
2395 current_child,
2396 ..
2397 } => {
2398 *current_child = Some(idx);
2399 data.get(idx)
2400 }
2401 _ => {
2402 return Err(ReflectError::OperationFailed {
2403 shape: frame.shape,
2404 operation: "selecting a field on an enum requires selecting a variant first",
2405 });
2406 }
2407 };
2408
2409 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2412 let field_shape = field.shape;
2413
2414 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2415 if was_field_init {
2416 unsafe {
2418 next_frame.mark_as_init();
2419 }
2420 }
2421
2422 Ok(next_frame)
2423 }
2424
2425 #[inline]
2427 pub(crate) fn require_active(&self) -> Result<(), ReflectError> {
2428 if self.state == PartialState::Active {
2429 Ok(())
2430 } else {
2431 Err(ReflectError::InvariantViolation {
2432 invariant: "Cannot use Partial after it has been built or poisoned",
2433 })
2434 }
2435 }
2436}