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
1235impl Partial<'_> {
1239 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
1241 crate::trace!("begin_smart_ptr()");
1242 self.require_active()?;
1243 let frame = self.frames.last_mut().unwrap();
1244
1245 match &frame.shape.def {
1247 Def::Pointer(smart_ptr_def) => {
1248 match smart_ptr_def.known {
1250 Some(KnownPointer::Box)
1251 | Some(KnownPointer::Rc)
1252 | Some(KnownPointer::Arc)
1253 | Some(KnownPointer::SharedReference) => {
1254 }
1256 _ => {
1257 return Err(ReflectError::OperationFailed {
1258 shape: frame.shape,
1259 operation: "only the following pointers are currently supported: Box<T>, Rc<T>, Arc<T>, and &T",
1260 });
1261 }
1262 }
1263
1264 let pointee_shape = match smart_ptr_def.pointee() {
1266 Some(shape) => shape,
1267 None => {
1268 return Err(ReflectError::OperationFailed {
1269 shape: frame.shape,
1270 operation: "Box must have a pointee shape",
1271 });
1272 }
1273 };
1274
1275 if pointee_shape.layout.sized_layout().is_ok() {
1276 if matches!(frame.tracker, Tracker::Uninit) {
1280 frame.tracker = Tracker::SmartPointer {
1281 is_initialized: false,
1282 };
1283 }
1284
1285 let inner_layout = match pointee_shape.layout.sized_layout() {
1286 Ok(layout) => layout,
1287 Err(_) => {
1288 return Err(ReflectError::Unsized {
1289 shape: pointee_shape,
1290 operation: "begin_smart_ptr, calculating inner value layout",
1291 });
1292 }
1293 };
1294 let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1295 if inner_ptr.is_null() {
1296 return Err(ReflectError::OperationFailed {
1297 shape: frame.shape,
1298 operation: "failed to allocate memory for smart pointer inner value",
1299 });
1300 }
1301
1302 self.frames.push(Frame::new(
1304 PtrUninit::new(inner_ptr),
1305 pointee_shape,
1306 FrameOwnership::Owned,
1307 ));
1308 } else {
1309 if pointee_shape == str::SHAPE {
1311 crate::trace!("Pointee is str");
1312
1313 let string_layout = String::SHAPE
1315 .layout
1316 .sized_layout()
1317 .expect("String must have a sized layout");
1318 let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1319 if string_ptr.is_null() {
1320 alloc::alloc::handle_alloc_error(string_layout);
1321 }
1322 let mut frame = Frame::new(
1323 PtrUninit::new(string_ptr),
1324 String::SHAPE,
1325 FrameOwnership::Owned,
1326 );
1327 frame.tracker = Tracker::Uninit;
1328 self.frames.push(frame);
1329 } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1330 crate::trace!("Pointee is [{}]", _st.t);
1331
1332 let slice_builder_vtable = smart_ptr_def
1334 .vtable
1335 .slice_builder_vtable
1336 .ok_or(ReflectError::OperationFailed {
1337 shape: frame.shape,
1338 operation: "smart pointer does not support slice building",
1339 })?;
1340
1341 let builder_ptr = (slice_builder_vtable.new_fn)();
1343
1344 if let FrameOwnership::Owned = frame.ownership {
1346 if let Ok(layout) = frame.shape.layout.sized_layout() {
1347 if layout.size() > 0 {
1348 unsafe {
1349 alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1350 };
1351 }
1352 }
1353 }
1354
1355 frame.data = PtrUninit::new(builder_ptr.as_mut_byte_ptr());
1357 frame.tracker = Tracker::SmartPointerSlice {
1358 vtable: slice_builder_vtable,
1359 building_item: false,
1360 };
1361 frame.ownership = FrameOwnership::ManagedElsewhere;
1363 } else {
1364 todo!("unsupported unsize pointee shape: {}", pointee_shape)
1365 }
1366 }
1367
1368 Ok(self)
1369 }
1370 _ => Err(ReflectError::OperationFailed {
1371 shape: frame.shape,
1372 operation: "push_smart_ptr can only be called on compatible types",
1373 }),
1374 }
1375 }
1376}
1377
1378impl Partial<'_> {
1382 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1390 crate::trace!("begin_list()");
1391 self.require_active()?;
1392 let frame = self.frames.last_mut().unwrap();
1393
1394 match &frame.tracker {
1395 Tracker::Uninit => {
1396 }
1398 Tracker::Init => {
1399 frame.tracker = Tracker::List {
1401 is_initialized: true,
1402 current_child: false,
1403 };
1404 return Ok(self);
1405 }
1406 Tracker::List { is_initialized, .. } => {
1407 if *is_initialized {
1408 return Ok(self);
1410 }
1411 }
1412 Tracker::SmartPointerSlice { .. } => {
1413 return Ok(self);
1415 }
1416 _ => {
1417 return Err(ReflectError::UnexpectedTracker {
1418 message: "begin_list called but tracker isn't something list-like",
1419 current_tracker: frame.tracker.kind(),
1420 });
1421 }
1422 };
1423
1424 let list_def = match &frame.shape.def {
1426 Def::List(list_def) => list_def,
1427 _ => {
1428 return Err(ReflectError::OperationFailed {
1429 shape: frame.shape,
1430 operation: "begin_list can only be called on List types",
1431 });
1432 }
1433 };
1434
1435 let init_fn = match list_def.vtable.init_in_place_with_capacity {
1437 Some(f) => f,
1438 None => {
1439 return Err(ReflectError::OperationFailed {
1440 shape: frame.shape,
1441 operation: "list type does not support initialization with capacity",
1442 });
1443 }
1444 };
1445
1446 unsafe {
1448 init_fn(frame.data, 0);
1449 }
1450
1451 frame.tracker = Tracker::List {
1453 is_initialized: true,
1454 current_child: false,
1455 };
1456
1457 Ok(self)
1458 }
1459
1460 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1463 crate::trace!("begin_list_item()");
1464 self.require_active()?;
1465 let frame = self.frames.last_mut().unwrap();
1466
1467 if let Tracker::SmartPointerSlice {
1469 building_item,
1470 vtable: _,
1471 } = &frame.tracker
1472 {
1473 if *building_item {
1474 return Err(ReflectError::OperationFailed {
1475 shape: frame.shape,
1476 operation: "already building an item, call end() first",
1477 });
1478 }
1479
1480 let element_shape = match &frame.shape.def {
1482 Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1483 Some(pointee_shape) => match &pointee_shape.ty {
1484 Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1485 _ => {
1486 return Err(ReflectError::OperationFailed {
1487 shape: frame.shape,
1488 operation: "smart pointer pointee is not a slice",
1489 });
1490 }
1491 },
1492 None => {
1493 return Err(ReflectError::OperationFailed {
1494 shape: frame.shape,
1495 operation: "smart pointer has no pointee",
1496 });
1497 }
1498 },
1499 _ => {
1500 return Err(ReflectError::OperationFailed {
1501 shape: frame.shape,
1502 operation: "expected smart pointer definition",
1503 });
1504 }
1505 };
1506
1507 crate::trace!("Pointee is a slice of {element_shape}");
1509 let element_layout = match element_shape.layout.sized_layout() {
1510 Ok(layout) => layout,
1511 Err(_) => {
1512 return Err(ReflectError::OperationFailed {
1513 shape: element_shape,
1514 operation: "cannot allocate unsized element",
1515 });
1516 }
1517 };
1518
1519 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1520 if element_ptr.is_null() {
1521 alloc::alloc::handle_alloc_error(element_layout);
1522 }
1523
1524 crate::trace!("Pushing element frame, which we just allocated");
1526 let element_frame = Frame::new(
1527 PtrUninit::new(element_ptr),
1528 element_shape,
1529 FrameOwnership::Owned,
1530 );
1531 self.frames.push(element_frame);
1532
1533 let parent_idx = self.frames.len() - 2;
1536 if let Tracker::SmartPointerSlice { building_item, .. } =
1537 &mut self.frames[parent_idx].tracker
1538 {
1539 crate::trace!("Marking element frame as building item");
1540 *building_item = true;
1541 }
1542
1543 return Ok(self);
1544 }
1545
1546 let list_def = match &frame.shape.def {
1548 Def::List(list_def) => list_def,
1549 _ => {
1550 return Err(ReflectError::OperationFailed {
1551 shape: frame.shape,
1552 operation: "push can only be called on List types",
1553 });
1554 }
1555 };
1556
1557 match &mut frame.tracker {
1559 Tracker::List {
1560 is_initialized: true,
1561 current_child,
1562 } => {
1563 if *current_child {
1564 return Err(ReflectError::OperationFailed {
1565 shape: frame.shape,
1566 operation: "already pushing an element, call pop() first",
1567 });
1568 }
1569 *current_child = true;
1570 }
1571 _ => {
1572 return Err(ReflectError::OperationFailed {
1573 shape: frame.shape,
1574 operation: "must call begin_list() before push()",
1575 });
1576 }
1577 }
1578
1579 let element_shape = list_def.t();
1581
1582 let element_layout = match element_shape.layout.sized_layout() {
1584 Ok(layout) => layout,
1585 Err(_) => {
1586 return Err(ReflectError::Unsized {
1587 shape: element_shape,
1588 operation: "begin_list_item: calculating element layout",
1589 });
1590 }
1591 };
1592 let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1593
1594 if element_ptr.is_null() {
1595 return Err(ReflectError::OperationFailed {
1596 shape: frame.shape,
1597 operation: "failed to allocate memory for list element",
1598 });
1599 }
1600
1601 self.frames.push(Frame::new(
1603 PtrUninit::new(element_ptr),
1604 element_shape,
1605 FrameOwnership::Owned,
1606 ));
1607
1608 Ok(self)
1609 }
1610}
1611
1612impl Partial<'_> {
1616 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1621 self.require_active()?;
1622 let frame = self.frames.last_mut().unwrap();
1623
1624 let map_def = match &frame.shape.def {
1626 Def::Map(map_def) => map_def,
1627 _ => {
1628 return Err(ReflectError::OperationFailed {
1629 shape: frame.shape,
1630 operation: "begin_map can only be called on Map types",
1631 });
1632 }
1633 };
1634
1635 let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1636
1637 unsafe {
1639 init_fn(frame.data, 0);
1640 }
1641
1642 frame.tracker = Tracker::Map {
1644 is_initialized: true,
1645 insert_state: MapInsertState::Idle,
1646 };
1647
1648 Ok(self)
1649 }
1650
1651 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1655 self.require_active()?;
1656 let frame = self.frames.last_mut().unwrap();
1657
1658 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1660 (
1661 Def::Map(map_def),
1662 Tracker::Map {
1663 is_initialized: true,
1664 insert_state,
1665 },
1666 ) => {
1667 match insert_state {
1668 MapInsertState::Idle => {
1669 *insert_state = MapInsertState::PushingKey { key_ptr: None };
1671 }
1672 MapInsertState::PushingKey { key_ptr } => {
1673 if key_ptr.is_some() {
1674 return Err(ReflectError::OperationFailed {
1675 shape: frame.shape,
1676 operation: "already pushing a key, call end() first",
1677 });
1678 }
1679 }
1680 _ => {
1681 return Err(ReflectError::OperationFailed {
1682 shape: frame.shape,
1683 operation: "must complete current operation before begin_key()",
1684 });
1685 }
1686 }
1687 map_def
1688 }
1689 _ => {
1690 return Err(ReflectError::OperationFailed {
1691 shape: frame.shape,
1692 operation: "must call begin_map() before begin_key()",
1693 });
1694 }
1695 };
1696
1697 let key_shape = map_def.k();
1699
1700 let key_layout = match key_shape.layout.sized_layout() {
1702 Ok(layout) => layout,
1703 Err(_) => {
1704 return Err(ReflectError::Unsized {
1705 shape: key_shape,
1706 operation: "begin_key allocating key",
1707 });
1708 }
1709 };
1710 let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1711 if key_ptr_raw.is_null() {
1712 return Err(ReflectError::OperationFailed {
1713 shape: frame.shape,
1714 operation: "failed to allocate memory for map key",
1715 });
1716 }
1717
1718 match &mut frame.tracker {
1720 Tracker::Map {
1721 insert_state: MapInsertState::PushingKey { key_ptr: kp },
1722 ..
1723 } => {
1724 *kp = Some(PtrUninit::new(key_ptr_raw));
1725 }
1726 _ => unreachable!(),
1727 }
1728
1729 self.frames.push(Frame::new(
1731 PtrUninit::new(key_ptr_raw),
1732 key_shape,
1733 FrameOwnership::ManagedElsewhere, ));
1735
1736 Ok(self)
1737 }
1738
1739 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1742 self.require_active()?;
1743 let frame = self.frames.last_mut().unwrap();
1744
1745 let map_def = match (&frame.shape.def, &mut frame.tracker) {
1747 (
1748 Def::Map(map_def),
1749 Tracker::Map {
1750 insert_state: MapInsertState::PushingValue { value_ptr, .. },
1751 ..
1752 },
1753 ) => {
1754 if value_ptr.is_some() {
1755 return Err(ReflectError::OperationFailed {
1756 shape: frame.shape,
1757 operation: "already pushing a value, call pop() first",
1758 });
1759 }
1760 map_def
1761 }
1762 _ => {
1763 return Err(ReflectError::OperationFailed {
1764 shape: frame.shape,
1765 operation: "must complete key before push_value()",
1766 });
1767 }
1768 };
1769
1770 let value_shape = map_def.v();
1772
1773 let value_layout = match value_shape.layout.sized_layout() {
1775 Ok(layout) => layout,
1776 Err(_) => {
1777 return Err(ReflectError::Unsized {
1778 shape: value_shape,
1779 operation: "begin_value allocating value",
1780 });
1781 }
1782 };
1783 let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1784
1785 if value_ptr_raw.is_null() {
1786 return Err(ReflectError::OperationFailed {
1787 shape: frame.shape,
1788 operation: "failed to allocate memory for map value",
1789 });
1790 }
1791
1792 match &mut frame.tracker {
1794 Tracker::Map {
1795 insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1796 ..
1797 } => {
1798 *vp = Some(PtrUninit::new(value_ptr_raw));
1799 }
1800 _ => unreachable!(),
1801 }
1802
1803 self.frames.push(Frame::new(
1805 PtrUninit::new(value_ptr_raw),
1806 value_shape,
1807 FrameOwnership::ManagedElsewhere, ));
1809
1810 Ok(self)
1811 }
1812}
1813
1814impl Partial<'_> {
1818 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
1820 self.require_active()?;
1821 let frame = self.frames.last_mut().unwrap();
1822
1823 let option_def = match frame.shape.def {
1825 Def::Option(def) => def,
1826 _ => {
1827 return Err(ReflectError::WasNotA {
1828 expected: "Option",
1829 actual: frame.shape,
1830 });
1831 }
1832 };
1833
1834 if matches!(frame.tracker, Tracker::Uninit) {
1836 frame.tracker = Tracker::Option {
1837 building_inner: true,
1838 };
1839 }
1840
1841 let inner_shape = option_def.t;
1843
1844 let inner_layout =
1846 inner_shape
1847 .layout
1848 .sized_layout()
1849 .map_err(|_| ReflectError::Unsized {
1850 shape: inner_shape,
1851 operation: "begin_some, allocating Option inner value",
1852 })?;
1853
1854 let inner_data = if inner_layout.size() == 0 {
1855 PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
1857 } else {
1858 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
1860 if ptr.is_null() {
1861 alloc::alloc::handle_alloc_error(inner_layout);
1862 }
1863 PtrUninit::new(ptr)
1864 };
1865
1866 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
1868 self.frames.push(inner_frame);
1869
1870 Ok(self)
1871 }
1872
1873 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
1875 self.require_active()?;
1876
1877 let (inner_shape, has_try_from, parent_shape) = {
1879 let frame = self.frames.last().unwrap();
1880 if let Some(inner_fn) = frame.shape.inner {
1881 let inner_shape = inner_fn();
1882 let has_try_from = frame
1883 .shape
1884 .vtable
1885 .sized()
1886 .and_then(|v| (v.try_from)())
1887 .is_some();
1888 (Some(inner_shape), has_try_from, frame.shape)
1889 } else {
1890 (None, false, frame.shape)
1891 }
1892 };
1893
1894 if let Some(inner_shape) = inner_shape {
1895 if has_try_from {
1896 let inner_layout =
1903 inner_shape
1904 .layout
1905 .sized_layout()
1906 .map_err(|_| ReflectError::Unsized {
1907 shape: inner_shape,
1908 operation: "begin_inner, getting inner layout",
1909 })?;
1910
1911 let inner_data = if inner_layout.size() == 0 {
1912 PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
1914 } else {
1915 let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
1917 if ptr.is_null() {
1918 alloc::alloc::handle_alloc_error(inner_layout);
1919 }
1920 PtrUninit::new(ptr)
1921 };
1922
1923 trace!(
1927 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
1928 );
1929 self.frames
1930 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
1931
1932 Ok(self)
1933 } else {
1934 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
1937 self.begin_nth_field(0)
1938 }
1939 } else {
1940 Err(ReflectError::OperationFailed {
1941 shape: parent_shape,
1942 operation: "type does not have an inner value",
1943 })
1944 }
1945 }
1946}
1947
1948impl<'facet> Partial<'facet> {
1952 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
1956 where
1957 U: Facet<'facet>,
1958 {
1959 self.begin_nth_field(idx)?.set(value)?.end()
1960 }
1961
1962 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
1964 where
1965 U: Facet<'facet>,
1966 {
1967 self.begin_field(field_name)?.set(value)?.end()
1968 }
1969
1970 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
1972 where
1973 U: Facet<'facet>,
1974 {
1975 self.begin_key()?.set(value)?.end()
1976 }
1977
1978 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
1980 where
1981 U: Facet<'facet>,
1982 {
1983 self.begin_value()?.set(value)?.end()
1984 }
1985
1986 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
1988 where
1989 U: Facet<'facet>,
1990 {
1991 self.begin_list_item()?.set(value)?.end()
1992 }
1993}
1994
1995impl<'facet> Partial<'facet> {
1999 fn select_variant_internal(
2008 &mut self,
2009 enum_type: &EnumType,
2010 variant: &'static Variant,
2011 ) -> Result<(), ReflectError> {
2012 let frame = self.frames.last().unwrap();
2014
2015 match enum_type.enum_repr {
2017 EnumRepr::RustNPO => {
2018 return Err(ReflectError::OperationFailed {
2019 shape: frame.shape,
2020 operation: "RustNPO enums are not supported for incremental building",
2021 });
2022 }
2023 EnumRepr::U8
2024 | EnumRepr::U16
2025 | EnumRepr::U32
2026 | EnumRepr::U64
2027 | EnumRepr::I8
2028 | EnumRepr::I16
2029 | EnumRepr::I32
2030 | EnumRepr::I64
2031 | EnumRepr::USize
2032 | EnumRepr::ISize => {
2033 }
2035 }
2036
2037 let Some(discriminant) = variant.discriminant else {
2038 return Err(ReflectError::OperationFailed {
2039 shape: frame.shape,
2040 operation: "trying to select an enum variant without a discriminant",
2041 });
2042 };
2043
2044 let fr = self.frames.last_mut().unwrap();
2046
2047 unsafe {
2049 match enum_type.enum_repr {
2050 EnumRepr::U8 => {
2051 let ptr = fr.data.as_mut_byte_ptr();
2052 *ptr = discriminant as u8;
2053 }
2054 EnumRepr::U16 => {
2055 let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
2056 *ptr = discriminant as u16;
2057 }
2058 EnumRepr::U32 => {
2059 let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
2060 *ptr = discriminant as u32;
2061 }
2062 EnumRepr::U64 => {
2063 let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
2064 *ptr = discriminant as u64;
2065 }
2066 EnumRepr::I8 => {
2067 let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
2068 *ptr = discriminant as i8;
2069 }
2070 EnumRepr::I16 => {
2071 let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
2072 *ptr = discriminant as i16;
2073 }
2074 EnumRepr::I32 => {
2075 let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
2076 *ptr = discriminant as i32;
2077 }
2078 EnumRepr::I64 => {
2079 let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
2080 *ptr = discriminant;
2081 }
2082 EnumRepr::USize => {
2083 let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
2084 *ptr = discriminant as usize;
2085 }
2086 EnumRepr::ISize => {
2087 let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
2088 *ptr = discriminant as isize;
2089 }
2090 _ => unreachable!("Already checked enum representation above"),
2091 }
2092 }
2093
2094 fr.tracker = Tracker::Enum {
2096 variant,
2097 data: ISet::new(variant.data.fields.len()),
2098 current_child: None,
2099 };
2100
2101 Ok(())
2102 }
2103
2104 fn get_fields(&self) -> Result<&'static [Field], ReflectError> {
2107 let frame = self.frames.last().unwrap();
2108 match frame.shape.ty {
2109 Type::Primitive(_) => Err(ReflectError::OperationFailed {
2110 shape: frame.shape,
2111 operation: "cannot select a field from a primitive type",
2112 }),
2113 Type::Sequence(_) => Err(ReflectError::OperationFailed {
2114 shape: frame.shape,
2115 operation: "cannot select a field from a sequence type",
2116 }),
2117 Type::User(user_type) => match user_type {
2118 UserType::Struct(struct_type) => Ok(struct_type.fields),
2119 UserType::Enum(_) => {
2120 let Tracker::Enum { variant, .. } = &frame.tracker else {
2121 return Err(ReflectError::OperationFailed {
2122 shape: frame.shape,
2123 operation: "must select variant before selecting enum fields",
2124 });
2125 };
2126 Ok(variant.data.fields)
2127 }
2128 UserType::Union(_) => Err(ReflectError::OperationFailed {
2129 shape: frame.shape,
2130 operation: "cannot select a field from a union type",
2131 }),
2132 UserType::Opaque => Err(ReflectError::OperationFailed {
2133 shape: frame.shape,
2134 operation: "opaque types cannot be reflected upon",
2135 }),
2136 },
2137 Type::Pointer(_) => Err(ReflectError::OperationFailed {
2138 shape: frame.shape,
2139 operation: "cannot select a field from a pointer type",
2140 }),
2141 }
2142 }
2143
2144 fn begin_nth_struct_field(
2146 frame: &mut Frame,
2147 struct_type: StructType,
2148 idx: usize,
2149 ) -> Result<Frame, ReflectError> {
2150 if idx >= struct_type.fields.len() {
2151 return Err(ReflectError::OperationFailed {
2152 shape: frame.shape,
2153 operation: "field index out of bounds",
2154 });
2155 }
2156 let field = &struct_type.fields[idx];
2157
2158 if !matches!(frame.tracker, Tracker::Struct { .. }) {
2159 frame.tracker = Tracker::Struct {
2160 iset: ISet::new(struct_type.fields.len()),
2161 current_child: None,
2162 }
2163 }
2164
2165 let was_field_init = match &mut frame.tracker {
2166 Tracker::Struct {
2167 iset,
2168 current_child,
2169 } => {
2170 *current_child = Some(idx);
2171 iset.get(idx)
2172 }
2173 _ => unreachable!(),
2174 };
2175
2176 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2178 let field_shape = field.shape;
2179
2180 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2181 if was_field_init {
2182 unsafe {
2183 next_frame.mark_as_init();
2185 }
2186 }
2187
2188 Ok(next_frame)
2189 }
2190
2191 fn begin_nth_array_element(
2193 frame: &mut Frame,
2194 array_type: ArrayType,
2195 idx: usize,
2196 ) -> Result<Frame, ReflectError> {
2197 if idx >= array_type.n {
2198 return Err(ReflectError::OperationFailed {
2199 shape: frame.shape,
2200 operation: "array index out of bounds",
2201 });
2202 }
2203
2204 if array_type.n > 63 {
2205 return Err(ReflectError::OperationFailed {
2206 shape: frame.shape,
2207 operation: "arrays larger than 63 elements are not yet supported",
2208 });
2209 }
2210
2211 match &frame.tracker {
2213 Tracker::Uninit => {
2214 frame.tracker = Tracker::Array {
2216 iset: ISet::default(),
2217 current_child: None,
2218 };
2219 }
2220 Tracker::Array { .. } => {
2221 }
2223 _other => {
2224 return Err(ReflectError::OperationFailed {
2225 shape: frame.shape,
2226 operation: "unexpected tracker state: expected Uninit or Array",
2227 });
2228 }
2229 }
2230
2231 match &mut frame.tracker {
2232 Tracker::Array {
2233 iset,
2234 current_child,
2235 } => {
2236 *current_child = Some(idx);
2237 let was_field_init = iset.get(idx);
2238
2239 let Ok(element_layout) = array_type.t.layout.sized_layout() else {
2241 return Err(ReflectError::Unsized {
2242 shape: array_type.t,
2243 operation: "begin_nth_element, calculating array element offset",
2244 });
2245 };
2246 let offset = element_layout.size() * idx;
2247 let element_data = unsafe { frame.data.field_uninit_at(offset) };
2248
2249 let mut next_frame = Frame::new(element_data, array_type.t, FrameOwnership::Field);
2250 if was_field_init {
2251 unsafe {
2253 next_frame.mark_as_init();
2254 }
2255 }
2256 Ok(next_frame)
2257 }
2258 _ => unreachable!(),
2259 }
2260 }
2261
2262 fn begin_nth_enum_field(
2264 frame: &mut Frame,
2265 variant: &'static Variant,
2266 idx: usize,
2267 ) -> Result<Frame, ReflectError> {
2268 if idx >= variant.data.fields.len() {
2269 return Err(ReflectError::OperationFailed {
2270 shape: frame.shape,
2271 operation: "enum field index out of bounds",
2272 });
2273 }
2274
2275 let field = &variant.data.fields[idx];
2276
2277 let was_field_init = match &mut frame.tracker {
2279 Tracker::Enum {
2280 data,
2281 current_child,
2282 ..
2283 } => {
2284 *current_child = Some(idx);
2285 data.get(idx)
2286 }
2287 _ => {
2288 return Err(ReflectError::OperationFailed {
2289 shape: frame.shape,
2290 operation: "selecting a field on an enum requires selecting a variant first",
2291 });
2292 }
2293 };
2294
2295 let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
2298 let field_shape = field.shape;
2299
2300 let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
2301 if was_field_init {
2302 unsafe {
2304 next_frame.mark_as_init();
2305 }
2306 }
2307
2308 Ok(next_frame)
2309 }
2310
2311 #[inline]
2313 pub(crate) fn require_active(&self) -> Result<(), ReflectError> {
2314 if self.state == PartialState::Active {
2315 Ok(())
2316 } else {
2317 Err(ReflectError::InvariantViolation {
2318 invariant: "Cannot use Partial after it has been built or poisoned",
2319 })
2320 }
2321 }
2322}