facet_reflect/partial/
mod.rs

1//! Partial value construction for dynamic reflection
2//!
3//! This module provides APIs for incrementally building values through reflection,
4//! particularly useful when deserializing data from external formats like JSON or YAML.
5//!
6//! # Overview
7//!
8//! The `Partial` type (formerly known as `Wip` - Work In Progress) allows you to:
9//! - Allocate memory for a value based on its `Shape`
10//! - Initialize fields incrementally in a type-safe manner
11//! - Handle complex nested structures including structs, enums, collections, and smart pointers
12//! - Build the final value once all required fields are initialized
13//!
14//! # Basic Usage
15//!
16//! ```no_run
17//! # use facet_reflect::Partial;
18//! # use facet_core::{Shape, Facet};
19//! # fn example<T: Facet<'static>>() -> Result<(), Box<dyn std::error::Error>> {
20//! // Allocate memory for a struct
21//! let mut partial = Partial::alloc::<T>()?;
22//!
23//! // Set simple fields
24//! partial.set_field("name", "Alice")?;
25//! partial.set_field("age", 30u32)?;
26//!
27//! // Work with nested structures
28//! partial.begin_field("address")?;
29//! partial.set_field("street", "123 Main St")?;
30//! partial.set_field("city", "Springfield")?;
31//! partial.end()?;
32//!
33//! // Build the final value
34//! let value = partial.build()?;
35//! # Ok(())
36//! # }
37//! ```
38//!
39//! # Chaining Style
40//!
41//! The API supports method chaining for cleaner code:
42//!
43//! ```no_run
44//! # use facet_reflect::Partial;
45//! # use facet_core::{Shape, Facet};
46//! # fn example<T: Facet<'static>>() -> Result<(), Box<dyn std::error::Error>> {
47//! let value = Partial::alloc::<T>()?
48//!     .set_field("name", "Bob")?
49//!     .begin_field("scores")?
50//!         .set(vec![95, 87, 92])?
51//!     .end()?
52//!     .build()?;
53//! # Ok(())
54//! # }
55//! ```
56//!
57//! # Working with Collections
58//!
59//! ```no_run
60//! # use facet_reflect::Partial;
61//! # use facet_core::{Shape, Facet};
62//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
63//! let mut partial = Partial::alloc::<Vec<String>>()?;
64//!
65//! // Add items to a list
66//! partial.begin_list_item()?;
67//! partial.set("first")?;
68//! partial.end()?;
69//!
70//! partial.begin_list_item()?;
71//! partial.set("second")?;
72//! partial.end()?;
73//!
74//! let vec = partial.build()?;
75//! # Ok(())
76//! # }
77//! ```
78//!
79//! # Working with Maps
80//!
81//! ```no_run
82//! # use facet_reflect::Partial;
83//! # use facet_core::{Shape, Facet};
84//! # use std::collections::HashMap;
85//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
86//! let mut partial = Partial::alloc::<HashMap<String, i32>>()?;
87//!
88//! // Insert key-value pairs
89//! partial.begin_key()?;
90//! partial.set("score")?;
91//! partial.end()?;
92//! partial.begin_value()?;
93//! partial.set(100i32)?;
94//! partial.end()?;
95//!
96//! let map = partial.build()?;
97//! # Ok(())
98//! # }
99//! ```
100//!
101//! # Safety and Memory Management
102//!
103//! The `Partial` type ensures memory safety by:
104//! - Tracking initialization state of all fields
105//! - Preventing use-after-build through state tracking
106//! - Properly handling drop semantics for partially initialized values
107//! - Supporting both owned and borrowed values through lifetime parameters
108
109#[cfg(test)]
110mod tests;
111
112use alloc::boxed::Box;
113use alloc::format;
114use alloc::string::{String, ToString};
115use alloc::vec;
116
117mod iset;
118
119use crate::{Peek, ReflectError, TrackerKind, trace};
120use facet_core::{DefaultInPlaceFn, SequenceType};
121
122use core::marker::PhantomData;
123
124mod heap_value;
125use alloc::vec::Vec;
126pub use heap_value::*;
127
128use facet_core::{
129    Def, EnumRepr, Facet, KnownPointer, PtrConst, PtrMut, PtrUninit, Shape, SliceBuilderVTable,
130    Type, UserType, Variant,
131};
132use iset::ISet;
133
134/// State of a partial value
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136enum PartialState {
137    /// Partial is active and can be modified
138    Active,
139    /// Partial has been successfully built and cannot be reused
140    Built,
141    /// Building failed and Partial is poisoned
142    BuildFailed,
143}
144
145/// A work-in-progress heap-allocated value
146///
147/// # Lifetimes
148///
149/// * `'facet`: The lifetime of borrowed values within the structure (or 'static if it's owned)
150/// * `'shape`: The lifetime of the Shape structure itself (often 'static)
151pub struct Partial<'facet> {
152    /// stack of frames to keep track of deeply nested initialization
153    frames: Vec<Frame>,
154
155    /// current state of the Partial
156    state: PartialState,
157
158    invariant: PhantomData<fn(&'facet ()) -> &'facet ()>,
159}
160
161#[derive(Clone, Copy, Debug)]
162enum MapInsertState {
163    /// Not currently inserting
164    Idle,
165    /// Pushing key
166    PushingKey {
167        /// Temporary storage for the key being built
168        key_ptr: Option<PtrUninit<'static>>,
169    },
170    /// Pushing value after key is done
171    PushingValue {
172        /// Temporary storage for the key that was built
173        key_ptr: PtrUninit<'static>,
174        /// Temporary storage for the value being built
175        value_ptr: Option<PtrUninit<'static>>,
176    },
177}
178
179#[derive(Debug)]
180enum FrameOwnership {
181    /// This frame owns the allocation and should deallocate it on drop
182    Owned,
183    /// This frame is a field pointer into a parent allocation
184    Field,
185    /// This frame's allocation is managed elsewhere (e.g., in MapInsertState)
186    ManagedElsewhere,
187}
188
189struct Frame {
190    /// Address of the value being initialized
191    data: PtrUninit<'static>,
192
193    /// Shape of the value being initialized
194    shape: &'static Shape,
195
196    /// Tracks initialized fields
197    tracker: Tracker,
198
199    /// Whether this frame owns the allocation or is just a field pointer
200    ownership: FrameOwnership,
201}
202
203#[derive(Debug)]
204enum Tracker {
205    /// Wholly uninitialized
206    Uninit,
207
208    /// Wholly initialized
209    Init,
210
211    /// Partially initialized array
212    Array {
213        /// Track which array elements are initialized (up to 63 elements)
214        iset: ISet,
215        /// If we're pushing another frame, this is set to the array index
216        current_child: Option<usize>,
217    },
218
219    /// Partially initialized struct/tuple-struct etc.
220    Struct {
221        /// fields need to be individually tracked — we only
222        /// support up to 63 fields.
223        iset: ISet,
224
225        /// if we're pushing another frame, this is set to the
226        /// index of the struct field
227        current_child: Option<usize>,
228    },
229
230    /// Smart pointer being initialized
231    SmartPointer {
232        /// Whether the inner value has been initialized
233        is_initialized: bool,
234    },
235
236    /// We're initializing an `Arc<str>`, `Box<str>`, `Rc<str>`, etc.
237    ///
238    /// We expect `set` with a `String`
239    SmartPointerStr {
240        // whether `data` was initialized with a `String` or not
241        is_initialized: bool,
242    },
243
244    /// We're initializing an `Arc<[T]>`, `Box<[T]>`, `Rc<[T]>`, etc.
245    ///
246    /// We're using the slice builder API to construct the slice
247    SmartPointerSlice {
248        /// The slice builder vtable
249        vtable: &'static SliceBuilderVTable,
250        /// Whether we're currently building an item to push
251        building_item: bool,
252    },
253
254    /// Partially initialized enum (but we picked a variant)
255    Enum {
256        variant: &'static Variant,
257        data: ISet,
258        /// If we're pushing another frame, this is set to the field index
259        current_child: Option<usize>,
260    },
261
262    /// Partially initialized list (Vec, etc.)
263    List {
264        /// The list has been initialized with capacity
265        is_initialized: bool,
266        /// If we're pushing another frame for an element
267        current_child: bool,
268    },
269
270    /// Partially initialized map (HashMap, BTreeMap, etc.)
271    Map {
272        /// The map has been initialized with capacity
273        is_initialized: bool,
274        /// State of the current insertion operation
275        insert_state: MapInsertState,
276    },
277
278    /// Option being initialized with Some(inner_value)
279    Option {
280        /// Whether we're currently building the inner value
281        building_inner: bool,
282    },
283}
284
285impl Tracker {
286    fn kind(&self) -> TrackerKind {
287        match self {
288            Tracker::Uninit => TrackerKind::Uninit,
289            Tracker::Init => TrackerKind::Init,
290            Tracker::Array { .. } => TrackerKind::Array,
291            Tracker::Struct { .. } => TrackerKind::Struct,
292            Tracker::SmartPointer { .. } => TrackerKind::SmartPointer,
293            Tracker::SmartPointerStr { .. } => TrackerKind::SmartPointerStr,
294            Tracker::SmartPointerSlice { .. } => TrackerKind::SmartPointerSlice,
295            Tracker::Enum { .. } => TrackerKind::Enum,
296            Tracker::List { .. } => TrackerKind::List,
297            Tracker::Map { .. } => TrackerKind::Map,
298            Tracker::Option { .. } => TrackerKind::Option,
299        }
300    }
301}
302
303impl Frame {
304    fn new(data: PtrUninit<'static>, shape: &'static Shape, ownership: FrameOwnership) -> Self {
305        // For empty structs (structs with 0 fields), start as Init since there's nothing to initialize
306        // This includes empty tuples () which are zero-sized types with no fields to initialize
307        let tracker = match shape.ty {
308            Type::User(UserType::Struct(struct_type)) if struct_type.fields.is_empty() => {
309                Tracker::Init
310            }
311            _ => Tracker::Uninit,
312        };
313
314        Self {
315            data,
316            shape,
317            tracker,
318            ownership,
319        }
320    }
321
322    /// Returns an error if the value is not fully initialized
323    fn require_full_initialization(&self) -> Result<(), ReflectError> {
324        match self.tracker {
325            Tracker::Uninit => Err(ReflectError::UninitializedValue { shape: self.shape }),
326            Tracker::Init => Ok(()),
327            Tracker::Array { iset, .. } => {
328                match self.shape.ty {
329                    Type::Sequence(facet_core::SequenceType::Array(array_def)) => {
330                        // Check if all array elements are initialized
331                        if (0..array_def.n).all(|idx| iset.get(idx)) {
332                            Ok(())
333                        } else {
334                            Err(ReflectError::UninitializedValue { shape: self.shape })
335                        }
336                    }
337                    _ => Err(ReflectError::UninitializedValue { shape: self.shape }),
338                }
339            }
340            Tracker::Struct { iset, .. } => {
341                if iset.all_set() {
342                    Ok(())
343                } else {
344                    // Attempt to find the first uninitialized field, if possible
345                    match self.shape.ty {
346                        Type::User(UserType::Struct(struct_type)) => {
347                            // Find index of the first bit not set
348                            let first_missing_idx =
349                                (0..struct_type.fields.len()).find(|&idx| !iset.get(idx));
350                            if let Some(missing_idx) = first_missing_idx {
351                                let field_name = struct_type.fields[missing_idx].name;
352                                Err(ReflectError::UninitializedField {
353                                    shape: self.shape,
354                                    field_name,
355                                })
356                            } else {
357                                // fallback, something went wrong
358                                Err(ReflectError::UninitializedValue { shape: self.shape })
359                            }
360                        }
361                        _ => Err(ReflectError::UninitializedValue { shape: self.shape }),
362                    }
363                }
364            }
365            Tracker::Enum { variant, data, .. } => {
366                // Check if all fields of the variant are initialized
367                let num_fields = variant.data.fields.len();
368                if num_fields == 0 {
369                    // Unit variant, always initialized
370                    Ok(())
371                } else if (0..num_fields).all(|idx| data.get(idx)) {
372                    Ok(())
373                } else {
374                    // Find the first uninitialized field
375                    let first_missing_idx = (0..num_fields).find(|&idx| !data.get(idx));
376                    if let Some(missing_idx) = first_missing_idx {
377                        let field_name = variant.data.fields[missing_idx].name;
378                        Err(ReflectError::UninitializedEnumField {
379                            shape: self.shape,
380                            field_name,
381                            variant_name: variant.name,
382                        })
383                    } else {
384                        Err(ReflectError::UninitializedValue { shape: self.shape })
385                    }
386                }
387            }
388            Tracker::SmartPointer { is_initialized } => {
389                if is_initialized {
390                    Ok(())
391                } else {
392                    Err(ReflectError::UninitializedValue { shape: self.shape })
393                }
394            }
395            Tracker::SmartPointerStr { is_initialized } => {
396                if is_initialized {
397                    Ok(())
398                } else {
399                    Err(ReflectError::UninitializedValue { shape: self.shape })
400                }
401            }
402            Tracker::SmartPointerSlice { building_item, .. } => {
403                if building_item {
404                    Err(ReflectError::UninitializedValue { shape: self.shape })
405                } else {
406                    Ok(())
407                }
408            }
409            Tracker::List { is_initialized, .. } => {
410                if is_initialized {
411                    Ok(())
412                } else {
413                    Err(ReflectError::UninitializedValue { shape: self.shape })
414                }
415            }
416            Tracker::Map {
417                is_initialized,
418                insert_state,
419            } => {
420                if is_initialized && matches!(insert_state, MapInsertState::Idle) {
421                    Ok(())
422                } else {
423                    Err(ReflectError::UninitializedValue { shape: self.shape })
424                }
425            }
426            Tracker::Option { building_inner } => {
427                if building_inner {
428                    Err(ReflectError::UninitializedValue { shape: self.shape })
429                } else {
430                    Ok(())
431                }
432            }
433        }
434    }
435}
436
437impl<'facet> Partial<'facet> {
438    /// Allocates a new Partial instance with the given shape
439    pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
440        crate::trace!(
441            "alloc_shape({:?}), with layout {:?}",
442            shape,
443            shape.layout.sized_layout()
444        );
445
446        let data = shape.allocate().map_err(|_| ReflectError::Unsized {
447            shape,
448            operation: "alloc_shape",
449        })?;
450
451        // Preallocate a couple of frames. The cost of allocating 4 frames is
452        // basically identical to allocating 1 frame, so for every type that
453        // has at least 1 level of nesting, this saves at least one guaranteed reallocation.
454        let mut frames = Vec::with_capacity(4);
455        frames.push(Frame::new(data, shape, FrameOwnership::Owned));
456
457        Ok(Self {
458            frames,
459            state: PartialState::Active,
460            invariant: PhantomData,
461        })
462    }
463
464    /// Allocates a new TypedPartial instance with the given shape and type
465    pub fn alloc<T>() -> Result<TypedPartial<'facet, T>, ReflectError>
466    where
467        T: Facet<'facet>,
468    {
469        Ok(TypedPartial {
470            inner: Self::alloc_shape(T::SHAPE)?,
471            phantom: PhantomData,
472        })
473    }
474
475    /// Creates a Partial from an existing pointer and shape (used for nested initialization)
476    pub fn from_ptr(data: PtrUninit<'_>, shape: &'static Shape) -> Self {
477        // We need to convert the lifetime, which is safe because we're storing it in a frame
478        // that will manage the lifetime correctly
479        let data_static = PtrUninit::new(data.as_mut_byte_ptr());
480        Self {
481            frames: vec![Frame::new(data_static, shape, FrameOwnership::Field)],
482            state: PartialState::Active,
483            invariant: PhantomData,
484        }
485    }
486
487    /// Require that the partial is active
488    fn require_active(&self) -> Result<(), ReflectError> {
489        if self.state == PartialState::Active {
490            Ok(())
491        } else {
492            Err(ReflectError::InvariantViolation {
493                invariant: "Cannot use Partial after it has been built or poisoned",
494            })
495        }
496    }
497
498    /// Returns the current frame count (depth of nesting)
499    #[inline]
500    pub fn frame_count(&self) -> usize {
501        self.frames.len()
502    }
503
504    /// Sets a value wholesale into the current frame
505    pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
506    where
507        U: Facet<'facet>,
508    {
509        self.require_active()?;
510
511        // For conversion frames, store the value in the conversion frame itself
512        // The conversion will happen during end()
513        let ptr_const = PtrConst::new(&raw const value);
514        unsafe {
515            // Safety: We are calling set_shape with a valid shape and a valid pointer
516            self.set_shape(ptr_const, U::SHAPE)?
517        };
518
519        // Prevent the value from being dropped since we've copied it
520        core::mem::forget(value);
521        Ok(self)
522    }
523
524    /// Sets a value into the current frame by shape, for shape-based operations
525    ///
526    /// If this returns Ok, then `src_value` has been moved out of
527    ///
528    /// # Safety
529    ///
530    /// The caller must ensure that `src_value` points to a valid instance of a value
531    /// whose memory layout and type matches `src_shape`, and that this value can be
532    /// safely copied (bitwise) into the destination specified by the Partial's current frame.
533    /// No automatic drop will be performed for any existing value, so calling this on an
534    /// already-initialized destination may result in leaks or double drops if misused.
535    /// After a successful call, the ownership of the value at `src_value` is effectively moved
536    /// into the Partial (i.e., the destination), and the original value should not be used
537    /// or dropped by the caller; consider using `core::mem::forget` on the passed value.
538    /// If an error is returned, the destination remains unmodified and safe for future operations.
539    #[inline]
540    pub unsafe fn set_shape(
541        &mut self,
542        src_value: PtrConst<'_>,
543        src_shape: &'static Shape,
544    ) -> Result<&mut Self, ReflectError> {
545        self.require_active()?;
546
547        let fr = self.frames.last_mut().unwrap();
548        crate::trace!("set_shape({src_shape:?})");
549        if !fr.shape.is_shape(src_shape) {
550            let err = ReflectError::WrongShape {
551                expected: fr.shape,
552                actual: src_shape,
553            };
554            return Err(err);
555        }
556
557        if fr.shape.layout.sized_layout().is_err() {
558            return Err(ReflectError::Unsized {
559                shape: fr.shape,
560                operation: "set_shape",
561            });
562        }
563
564        let mut need_drop = false;
565        match fr.tracker {
566            Tracker::Uninit => {
567                // good! that's the easy path
568            }
569            Tracker::Init => {
570                need_drop = true;
571            }
572            Tracker::Array { .. } => {
573                todo!("deinitializing select array fields on set_shape is not implemented yet")
574            }
575            Tracker::Struct { .. } => {
576                todo!("deinitializing select struct fields on set_shape is not implemented yet")
577            }
578            Tracker::SmartPointer { is_initialized } => need_drop = is_initialized,
579            Tracker::SmartPointerStr { is_initialized } => need_drop = is_initialized,
580            Tracker::SmartPointerSlice { .. } => {
581                todo!("deinitializing smart pointer str on set_shape is not implemented yet")
582            }
583            Tracker::Enum { .. } => {
584                // if we have a Tracker::Enum that means a variant was selected,
585                // but it might only be partially initialized
586                todo!("deinitializing select enum fields on set_shape is not implemented yet")
587            }
588            Tracker::List { is_initialized, .. } => need_drop = is_initialized,
589            Tracker::Map { is_initialized, .. } => need_drop = is_initialized,
590            Tracker::Option { .. } => todo!(),
591        }
592
593        if need_drop {
594            let drop_in_place = (fr.shape.vtable.sized().unwrap().drop_in_place)();
595            crate::trace!(
596                "set_shape: should drop first (has drop? {:?})",
597                drop_in_place.is_some()
598            );
599
600            if let Some(drop_in_place) = drop_in_place {
601                unsafe {
602                    (drop_in_place)(fr.data.assume_init());
603                }
604            }
605        }
606
607        unsafe {
608            fr.data.copy_from(src_value, fr.shape).unwrap();
609        }
610
611        match &mut fr.tracker {
612            Tracker::SmartPointerStr { is_initialized } => {
613                *is_initialized = true;
614            }
615            _ => {
616                fr.tracker = Tracker::Init;
617            }
618        }
619
620        Ok(self)
621    }
622
623    /// Sets the current frame to its default value
624    #[inline]
625    pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
626        let frame = self.frames.last().unwrap(); // Get frame to access vtable
627
628        if let Some(default_fn) = frame
629            .shape
630            .vtable
631            .sized()
632            .and_then(|v| (v.default_in_place)())
633        {
634            // Initialize with default value using set_from_function
635            // SAFETY: set_from_function handles the active check, dropping,
636            // and setting tracker. The closure passes the correct pointer type
637            // and casts to 'static which is safe within the context of calling
638            // the vtable function. The closure returns Ok(()) because the
639            // default_in_place function does not return errors.
640            self.set_from_function(move |ptr: PtrUninit<'_>| {
641                unsafe { default_fn(PtrUninit::new(ptr.as_mut_byte_ptr())) };
642                Ok(())
643            })
644        } else {
645            // Default function not available, set state and return error
646            Err(ReflectError::OperationFailed {
647                shape: frame.shape,
648                operation: "type does not implement Default",
649            })
650        }
651    }
652
653    /// Sets the current frame using a field-level default function
654    #[inline]
655    pub fn set_field_default(
656        &mut self,
657        field_default_fn: DefaultInPlaceFn,
658    ) -> Result<&mut Self, ReflectError> {
659        // Use the field-level default function to initialize the value
660        // SAFETY: set_from_function handles the active check, dropping,
661        // and setting tracker. The closure passes the correct pointer type
662        // and casts to 'static which is safe within the context of calling
663        // the field vtable function. The closure returns Ok(()) because the
664        // default function does not return errors.
665        self.set_from_function(move |ptr: PtrUninit<'_>| {
666            unsafe { field_default_fn(PtrUninit::new(ptr.as_mut_byte_ptr())) };
667            Ok(())
668        })
669    }
670
671    /// Sets the current frame using a function that initializes the value
672    pub fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
673    where
674        F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
675    {
676        self.require_active()?;
677
678        let frame = self.frames.last_mut().unwrap();
679
680        // Check if we need to drop an existing value
681        if matches!(frame.tracker, Tracker::Init) {
682            if let Some(drop_fn) = frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)()) {
683                unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
684            }
685        }
686
687        // Don't allow overwriting when building an Option's inner value
688        if matches!(
689            frame.tracker,
690            Tracker::Option {
691                building_inner: true
692            }
693        ) {
694            return Err(ReflectError::OperationFailed {
695                shape: frame.shape,
696                operation: "Cannot overwrite while building Option inner value",
697            });
698        }
699
700        // Call the function to initialize the value
701        match f(frame.data) {
702            Ok(()) => {
703                // FIXME: what about finding out the discriminant of enums?
704                frame.tracker = Tracker::Init;
705                Ok(self)
706            }
707            Err(e) => Err(e),
708        }
709    }
710
711    /// Parses a string value into the current frame using the type's ParseFn from the vtable
712    pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
713        self.require_active()?;
714
715        let frame = self.frames.last_mut().unwrap();
716
717        // Check if the type has a parse function
718        let parse_fn = match frame.shape.vtable.sized().and_then(|v| (v.parse)()) {
719            Some(parse_fn) => parse_fn,
720            None => {
721                return Err(ReflectError::OperationFailed {
722                    shape: frame.shape,
723                    operation: "Type does not support parsing from string",
724                });
725            }
726        };
727
728        // Check if we need to drop an existing value
729        if matches!(frame.tracker, Tracker::Init) {
730            if let Some(drop_fn) = frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)()) {
731                unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
732            }
733        }
734
735        // Don't allow overwriting when building an Option's inner value
736        if matches!(
737            frame.tracker,
738            Tracker::Option {
739                building_inner: true
740            }
741        ) {
742            return Err(ReflectError::OperationFailed {
743                shape: frame.shape,
744                operation: "Cannot overwrite while building Option inner value",
745            });
746        }
747
748        // Parse the string value using the type's parse function
749        let result = unsafe { parse_fn(s, frame.data) };
750        match result {
751            Ok(_) => {
752                frame.tracker = Tracker::Init;
753                Ok(self)
754            }
755            Err(_parse_error) => Err(ReflectError::OperationFailed {
756                shape: frame.shape,
757                operation: "Failed to parse string value",
758            }),
759        }
760    }
761
762    /// Pushes a variant for enum initialization by name
763    pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
764        self.require_active()?;
765
766        let fr = self.frames.last_mut().unwrap();
767
768        // Check that we're dealing with an enum
769        let enum_type = match fr.shape.ty {
770            Type::User(UserType::Enum(e)) => e,
771            _ => {
772                return Err(ReflectError::OperationFailed {
773                    shape: fr.shape,
774                    operation: "push_variant_named requires an enum type",
775                });
776            }
777        };
778
779        // Find the variant with the matching name
780        let variant = match enum_type.variants.iter().find(|v| v.name == variant_name) {
781            Some(v) => v,
782            None => {
783                return Err(ReflectError::OperationFailed {
784                    shape: fr.shape,
785                    operation: "No variant found with the given name",
786                });
787            }
788        };
789
790        // Get the discriminant value
791        let discriminant = match variant.discriminant {
792            Some(d) => d,
793            None => {
794                return Err(ReflectError::OperationFailed {
795                    shape: fr.shape,
796                    operation: "Variant has no discriminant value",
797                });
798            }
799        };
800
801        // Delegate to push_variant
802        self.select_variant(discriminant)
803    }
804
805    /// Pushes a variant for enum initialization
806    pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
807        self.require_active()?;
808
809        // Check all invariants early before making any changes
810        let fr = self.frames.last().unwrap();
811
812        // Check that we're dealing with an enum
813        let enum_type = match fr.shape.ty {
814            Type::User(UserType::Enum(e)) => e,
815            _ => {
816                return Err(ReflectError::WasNotA {
817                    expected: "enum",
818                    actual: fr.shape,
819                });
820            }
821        };
822
823        // Find the variant with the matching discriminant
824        let variant = match enum_type
825            .variants
826            .iter()
827            .find(|v| v.discriminant == Some(discriminant))
828        {
829            Some(v) => v,
830            None => {
831                return Err(ReflectError::OperationFailed {
832                    shape: fr.shape,
833                    operation: "No variant found with the given discriminant",
834                });
835            }
836        };
837
838        // Check enum representation early
839        match enum_type.enum_repr {
840            EnumRepr::RustNPO => {
841                return Err(ReflectError::OperationFailed {
842                    shape: fr.shape,
843                    operation: "RustNPO enums are not supported for incremental building",
844                });
845            }
846            EnumRepr::U8
847            | EnumRepr::U16
848            | EnumRepr::U32
849            | EnumRepr::U64
850            | EnumRepr::I8
851            | EnumRepr::I16
852            | EnumRepr::I32
853            | EnumRepr::I64
854            | EnumRepr::USize
855            | EnumRepr::ISize => {
856                // These are supported, continue
857            }
858        }
859
860        // All checks passed, now we can safely make changes
861        let fr = self.frames.last_mut().unwrap();
862
863        // Write the discriminant to memory
864        unsafe {
865            match enum_type.enum_repr {
866                EnumRepr::U8 => {
867                    let ptr = fr.data.as_mut_byte_ptr();
868                    *ptr = discriminant as u8;
869                }
870                EnumRepr::U16 => {
871                    let ptr = fr.data.as_mut_byte_ptr() as *mut u16;
872                    *ptr = discriminant as u16;
873                }
874                EnumRepr::U32 => {
875                    let ptr = fr.data.as_mut_byte_ptr() as *mut u32;
876                    *ptr = discriminant as u32;
877                }
878                EnumRepr::U64 => {
879                    let ptr = fr.data.as_mut_byte_ptr() as *mut u64;
880                    *ptr = discriminant as u64;
881                }
882                EnumRepr::I8 => {
883                    let ptr = fr.data.as_mut_byte_ptr() as *mut i8;
884                    *ptr = discriminant as i8;
885                }
886                EnumRepr::I16 => {
887                    let ptr = fr.data.as_mut_byte_ptr() as *mut i16;
888                    *ptr = discriminant as i16;
889                }
890                EnumRepr::I32 => {
891                    let ptr = fr.data.as_mut_byte_ptr() as *mut i32;
892                    *ptr = discriminant as i32;
893                }
894                EnumRepr::I64 => {
895                    let ptr = fr.data.as_mut_byte_ptr() as *mut i64;
896                    *ptr = discriminant;
897                }
898                EnumRepr::USize => {
899                    let ptr = fr.data.as_mut_byte_ptr() as *mut usize;
900                    *ptr = discriminant as usize;
901                }
902                EnumRepr::ISize => {
903                    let ptr = fr.data.as_mut_byte_ptr() as *mut isize;
904                    *ptr = discriminant as isize;
905                }
906                _ => unreachable!("Already checked enum representation above"),
907            }
908        }
909
910        // Update tracker to track the variant
911        fr.tracker = Tracker::Enum {
912            variant,
913            data: ISet::new(variant.data.fields.len()),
914            current_child: None,
915        };
916
917        Ok(self)
918    }
919
920    /// Selects a field of a struct with a given name
921    pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
922        self.require_active()?;
923
924        let frame = self.frames.last_mut().unwrap();
925        match frame.shape.ty {
926            Type::Primitive(_) => Err(ReflectError::OperationFailed {
927                shape: frame.shape,
928                operation: "cannot select a field from a primitive type",
929            }),
930            Type::Sequence(_) => Err(ReflectError::OperationFailed {
931                shape: frame.shape,
932                operation: "cannot select a field from a sequence type",
933            }),
934            Type::User(user_type) => match user_type {
935                UserType::Struct(struct_type) => {
936                    let idx = struct_type.fields.iter().position(|f| f.name == field_name);
937                    let idx = match idx {
938                        Some(idx) => idx,
939                        None => {
940                            return Err(ReflectError::OperationFailed {
941                                shape: frame.shape,
942                                operation: "field not found",
943                            });
944                        }
945                    };
946                    self.begin_nth_field(idx)
947                }
948                UserType::Enum(_) => {
949                    // Check if we have a variant selected
950                    match &frame.tracker {
951                        Tracker::Enum { variant, .. } => {
952                            let idx = variant
953                                .data
954                                .fields
955                                .iter()
956                                .position(|f| f.name == field_name);
957                            let idx = match idx {
958                                Some(idx) => idx,
959                                None => {
960                                    return Err(ReflectError::OperationFailed {
961                                        shape: frame.shape,
962                                        operation: "field not found in current enum variant",
963                                    });
964                                }
965                            };
966                            self.begin_nth_enum_field(idx)
967                        }
968                        _ => Err(ReflectError::OperationFailed {
969                            shape: frame.shape,
970                            operation: "must call push_variant before selecting enum fields",
971                        }),
972                    }
973                }
974                UserType::Union(_) => Err(ReflectError::OperationFailed {
975                    shape: frame.shape,
976                    operation: "unions are not supported",
977                }),
978                UserType::Opaque => Err(ReflectError::OperationFailed {
979                    shape: frame.shape,
980                    operation: "opaque types cannot be reflected upon",
981                }),
982            },
983            Type::Pointer(_) => Err(ReflectError::OperationFailed {
984                shape: frame.shape,
985                operation: "cannot select a field from a pointer type",
986            }),
987        }
988    }
989
990    /// Selects a variant for enum initialization, by variant index in the enum's variant list (0-based)
991    pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
992        self.require_active()?;
993
994        let fr = self.frames.last().unwrap();
995
996        // Check that we're dealing with an enum
997        let enum_type = match fr.shape.ty {
998            Type::User(UserType::Enum(e)) => e,
999            _ => {
1000                return Err(ReflectError::OperationFailed {
1001                    shape: fr.shape,
1002                    operation: "select_nth_variant requires an enum type",
1003                });
1004            }
1005        };
1006
1007        if index >= enum_type.variants.len() {
1008            return Err(ReflectError::OperationFailed {
1009                shape: fr.shape,
1010                operation: "variant index out of bounds",
1011            });
1012        }
1013        let variant = &enum_type.variants[index];
1014
1015        // Get the discriminant value
1016        let discriminant = match variant.discriminant {
1017            Some(d) => d,
1018            None => {
1019                return Err(ReflectError::OperationFailed {
1020                    shape: fr.shape,
1021                    operation: "Variant has no discriminant value",
1022                });
1023            }
1024        };
1025
1026        // Delegate to select_variant
1027        self.select_variant(discriminant)
1028    }
1029
1030    /// Selects the nth field of a struct by index
1031    pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1032        self.require_active()?;
1033        let frame = self.frames.last_mut().unwrap();
1034        match frame.shape.ty {
1035            Type::User(user_type) => match user_type {
1036                UserType::Struct(struct_type) => {
1037                    if idx >= struct_type.fields.len() {
1038                        return Err(ReflectError::OperationFailed {
1039                            shape: frame.shape,
1040                            operation: "field index out of bounds",
1041                        });
1042                    }
1043                    let field = &struct_type.fields[idx];
1044                    let mut is_field_init = false;
1045
1046                    match &mut frame.tracker {
1047                        Tracker::Uninit => {
1048                            frame.tracker = Tracker::Struct {
1049                                iset: ISet::new(struct_type.fields.len()),
1050                                current_child: Some(idx),
1051                            }
1052                        }
1053                        Tracker::Struct {
1054                            iset,
1055                            current_child,
1056                        } => {
1057                            // Check if this field was already initialized
1058                            if iset.get(idx) {
1059                                is_field_init = true;
1060                            }
1061                            *current_child = Some(idx);
1062                        }
1063                        _ => unreachable!(),
1064                    }
1065
1066                    // Push a new frame for this field onto the frames stack.
1067                    let field_ptr = unsafe { frame.data.field_uninit_at(field.offset) };
1068                    let field_shape = field.shape;
1069                    let mut next_frame = Frame::new(field_ptr, field_shape, FrameOwnership::Field);
1070                    if is_field_init {
1071                        next_frame.tracker = Tracker::Init;
1072                    }
1073                    self.frames.push(next_frame);
1074
1075                    Ok(self)
1076                }
1077                UserType::Enum(_) => {
1078                    // Check if we have a variant selected
1079                    match &frame.tracker {
1080                        Tracker::Enum { variant, .. } => {
1081                            if idx >= variant.data.fields.len() {
1082                                return Err(ReflectError::OperationFailed {
1083                                    shape: frame.shape,
1084                                    operation: "enum field index out of bounds",
1085                                });
1086                            }
1087                            self.begin_nth_enum_field(idx)
1088                        }
1089                        _ => Err(ReflectError::OperationFailed {
1090                            shape: frame.shape,
1091                            operation: "must call select_variant before selecting enum fields",
1092                        }),
1093                    }
1094                }
1095                UserType::Union(_) => Err(ReflectError::OperationFailed {
1096                    shape: frame.shape,
1097                    operation: "unions are not supported",
1098                }),
1099                UserType::Opaque => Err(ReflectError::OperationFailed {
1100                    shape: frame.shape,
1101                    operation: "opaque types cannot be reflected upon",
1102                }),
1103            },
1104            _ => Err(ReflectError::OperationFailed {
1105                shape: frame.shape,
1106                operation: "cannot select a field from this type",
1107            }),
1108        }
1109    }
1110
1111    /// Selects the nth element of an array by index
1112    pub fn begin_nth_element(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1113        self.require_active()?;
1114        let frame = self.frames.last_mut().unwrap();
1115        match frame.shape.ty {
1116            Type::Sequence(seq_type) => match seq_type {
1117                facet_core::SequenceType::Array(array_def) => {
1118                    if idx >= array_def.n {
1119                        return Err(ReflectError::OperationFailed {
1120                            shape: frame.shape,
1121                            operation: "array index out of bounds",
1122                        });
1123                    }
1124
1125                    if array_def.n > 63 {
1126                        return Err(ReflectError::OperationFailed {
1127                            shape: frame.shape,
1128                            operation: "arrays larger than 63 elements are not yet supported",
1129                        });
1130                    }
1131
1132                    // Ensure frame is in Array state
1133                    if matches!(frame.tracker, Tracker::Uninit) {
1134                        frame.tracker = Tracker::Array {
1135                            iset: ISet::default(),
1136                            current_child: None,
1137                        };
1138                    }
1139
1140                    match &mut frame.tracker {
1141                        Tracker::Array {
1142                            iset,
1143                            current_child,
1144                        } => {
1145                            // Calculate the offset for this array element
1146                            let element_layout = match array_def.t.layout.sized_layout() {
1147                                Ok(layout) => layout,
1148                                Err(_) => {
1149                                    return Err(ReflectError::Unsized {
1150                                        shape: array_def.t,
1151                                        operation: "begin_nth_element, calculating array element offset",
1152                                    });
1153                                }
1154                            };
1155                            let offset = element_layout.size() * idx;
1156
1157                            // Check if this element was already initialized
1158                            if iset.get(idx) {
1159                                // Drop the existing value before re-initializing
1160                                let element_ptr = unsafe { frame.data.field_init_at(offset) };
1161                                if let Some(drop_fn) =
1162                                    array_def.t.vtable.sized().and_then(|v| (v.drop_in_place)())
1163                                {
1164                                    unsafe { drop_fn(element_ptr) };
1165                                }
1166                                // Unset the bit so we can re-initialize
1167                                iset.unset(idx);
1168                            }
1169
1170                            *current_child = Some(idx);
1171
1172                            // Create a new frame for the array element
1173                            let element_data = unsafe { frame.data.field_uninit_at(offset) };
1174                            self.frames.push(Frame::new(
1175                                element_data,
1176                                array_def.t,
1177                                FrameOwnership::Field,
1178                            ));
1179
1180                            Ok(self)
1181                        }
1182                        _ => Err(ReflectError::OperationFailed {
1183                            shape: frame.shape,
1184                            operation: "expected array tracker state",
1185                        }),
1186                    }
1187                }
1188                _ => Err(ReflectError::OperationFailed {
1189                    shape: frame.shape,
1190                    operation: "can only select elements from arrays",
1191                }),
1192            },
1193            _ => Err(ReflectError::OperationFailed {
1194                shape: frame.shape,
1195                operation: "cannot select an element from this type",
1196            }),
1197        }
1198    }
1199
1200    /// Selects the nth field of an enum variant by index
1201    pub fn begin_nth_enum_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
1202        self.require_active()?;
1203        let frame = self.frames.last_mut().unwrap();
1204
1205        // Ensure we're in an enum with a variant selected
1206        let (variant, enum_type) = match (&frame.tracker, &frame.shape.ty) {
1207            (Tracker::Enum { variant, .. }, Type::User(UserType::Enum(e))) => (variant, e),
1208            _ => {
1209                return Err(ReflectError::OperationFailed {
1210                    shape: frame.shape,
1211                    operation: "push_nth_enum_field requires an enum with a variant selected",
1212                });
1213            }
1214        };
1215
1216        // Check bounds
1217        if idx >= variant.data.fields.len() {
1218            return Err(ReflectError::OperationFailed {
1219                shape: frame.shape,
1220                operation: "enum field index out of bounds",
1221            });
1222        }
1223
1224        let field = &variant.data.fields[idx];
1225
1226        // Update tracker
1227        match &mut frame.tracker {
1228            Tracker::Enum {
1229                data,
1230                current_child,
1231                ..
1232            } => {
1233                // Check if field was already initialized and drop if needed
1234                if data.get(idx) {
1235                    // Calculate the field offset, taking into account the discriminant
1236                    let _discriminant_size = match enum_type.enum_repr {
1237                        EnumRepr::U8 | EnumRepr::I8 => 1,
1238                        EnumRepr::U16 | EnumRepr::I16 => 2,
1239                        EnumRepr::U32 | EnumRepr::I32 => 4,
1240                        EnumRepr::U64 | EnumRepr::I64 => 8,
1241                        EnumRepr::USize | EnumRepr::ISize => core::mem::size_of::<usize>(),
1242                        EnumRepr::RustNPO => {
1243                            return Err(ReflectError::OperationFailed {
1244                                shape: frame.shape,
1245                                operation: "RustNPO enums are not supported",
1246                            });
1247                        }
1248                    };
1249
1250                    // The field offset already includes the discriminant offset
1251                    let field_ptr = unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
1252
1253                    if let Some(drop_fn) =
1254                        field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
1255                    {
1256                        unsafe { drop_fn(PtrMut::new(field_ptr)) };
1257                    }
1258
1259                    // Unset the bit so we can re-initialize
1260                    data.unset(idx);
1261                }
1262
1263                // Set current_child to track which field we're initializing
1264                *current_child = Some(idx);
1265            }
1266            _ => unreachable!("Already checked that we have Enum tracker"),
1267        }
1268
1269        // Extract data we need before pushing frame
1270        let field_ptr = unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
1271        let field_shape = field.shape;
1272
1273        // Push new frame for the field
1274        self.frames.push(Frame::new(
1275            PtrUninit::new(field_ptr),
1276            field_shape,
1277            FrameOwnership::Field,
1278        ));
1279
1280        Ok(self)
1281    }
1282
1283    /// Pushes a frame to initialize the inner value of a smart pointer (`Box<T>`, `Arc<T>`, etc.)
1284    pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
1285        crate::trace!("begin_smart_ptr()");
1286        self.require_active()?;
1287        let frame = self.frames.last_mut().unwrap();
1288
1289        // Check that we have a SmartPointer
1290        match &frame.shape.def {
1291            Def::Pointer(smart_ptr_def) => {
1292                // Check for supported smart pointer types
1293                match smart_ptr_def.known {
1294                    Some(KnownPointer::Box)
1295                    | Some(KnownPointer::Rc)
1296                    | Some(KnownPointer::Arc)
1297                    | Some(KnownPointer::SharedReference) => {
1298                        // Supported types, continue
1299                    }
1300                    _ => {
1301                        return Err(ReflectError::OperationFailed {
1302                            shape: frame.shape,
1303                            operation: "only the following pointers are currently supported: Box<T>, Rc<T>, Arc<T>, and &T",
1304                        });
1305                    }
1306                }
1307
1308                // Get the pointee shape
1309                let pointee_shape = match smart_ptr_def.pointee() {
1310                    Some(shape) => shape,
1311                    None => {
1312                        return Err(ReflectError::OperationFailed {
1313                            shape: frame.shape,
1314                            operation: "Box must have a pointee shape",
1315                        });
1316                    }
1317                };
1318
1319                if pointee_shape.layout.sized_layout().is_ok() {
1320                    // pointee is sized, we can allocate it — for `Arc<T>` we'll be allocating a `T` and
1321                    // holding onto it. We'll build a new Arc with it when ending the smart pointer frame.
1322
1323                    if matches!(frame.tracker, Tracker::Uninit) {
1324                        frame.tracker = Tracker::SmartPointer {
1325                            is_initialized: false,
1326                        };
1327                    }
1328
1329                    let inner_layout = match pointee_shape.layout.sized_layout() {
1330                        Ok(layout) => layout,
1331                        Err(_) => {
1332                            return Err(ReflectError::Unsized {
1333                                shape: pointee_shape,
1334                                operation: "begin_smart_ptr, calculating inner value layout",
1335                            });
1336                        }
1337                    };
1338                    let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1339                    if inner_ptr.is_null() {
1340                        return Err(ReflectError::OperationFailed {
1341                            shape: frame.shape,
1342                            operation: "failed to allocate memory for smart pointer inner value",
1343                        });
1344                    }
1345
1346                    // Push a new frame for the inner value
1347                    self.frames.push(Frame::new(
1348                        PtrUninit::new(inner_ptr),
1349                        pointee_shape,
1350                        FrameOwnership::Owned,
1351                    ));
1352                } else {
1353                    // pointee is unsized, we only support a handful of cases there
1354                    if pointee_shape == str::SHAPE {
1355                        crate::trace!("Pointee is str");
1356
1357                        // Allocate space for a String
1358                        let string_layout = String::SHAPE
1359                            .layout
1360                            .sized_layout()
1361                            .expect("String must have a sized layout");
1362                        let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1363                        if string_ptr.is_null() {
1364                            alloc::alloc::handle_alloc_error(string_layout);
1365                        }
1366                        let mut frame = Frame::new(
1367                            PtrUninit::new(string_ptr),
1368                            String::SHAPE,
1369                            FrameOwnership::Owned,
1370                        );
1371                        frame.tracker = Tracker::SmartPointerStr {
1372                            is_initialized: false,
1373                        };
1374                        self.frames.push(frame);
1375                    } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1376                        crate::trace!("Pointee is [{}]", _st.t);
1377
1378                        // Get the slice builder vtable
1379                        let slice_builder_vtable = smart_ptr_def
1380                            .vtable
1381                            .slice_builder_vtable
1382                            .ok_or(ReflectError::OperationFailed {
1383                                shape: frame.shape,
1384                                operation: "smart pointer does not support slice building",
1385                            })?;
1386
1387                        // Create a new builder
1388                        let builder_ptr = (slice_builder_vtable.new_fn)();
1389
1390                        // Deallocate the original Arc allocation before replacing with slice builder
1391                        if let FrameOwnership::Owned = frame.ownership {
1392                            if let Ok(layout) = frame.shape.layout.sized_layout() {
1393                                if layout.size() > 0 {
1394                                    unsafe {
1395                                        alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1396                                    };
1397                                }
1398                            }
1399                        }
1400
1401                        // Update the current frame to use the slice builder
1402                        frame.data = PtrUninit::new(builder_ptr.as_mut_byte_ptr());
1403                        frame.tracker = Tracker::SmartPointerSlice {
1404                            vtable: slice_builder_vtable,
1405                            building_item: false,
1406                        };
1407                        // The slice builder memory is managed by the vtable, not by us
1408                        frame.ownership = FrameOwnership::ManagedElsewhere;
1409                    } else {
1410                        todo!("unsupported unsize pointee shape: {}", pointee_shape)
1411                    }
1412                }
1413
1414                Ok(self)
1415            }
1416            _ => Err(ReflectError::OperationFailed {
1417                shape: frame.shape,
1418                operation: "push_smart_ptr can only be called on compatible types",
1419            }),
1420        }
1421    }
1422
1423    /// Initializes a list (Vec, etc.) if it hasn't been initialized before.
1424    /// This is a prerequisite to `begin_push_item`/`set`/`end` or the shorthand
1425    /// `push`.
1426    ///
1427    /// `begin_list` does not clear the list if it was previously initialized.
1428    /// `begin_list` does not push a new frame to the stack, and thus does not
1429    /// require `end` to be called afterwards.
1430    pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
1431        crate::trace!("begin_list()");
1432        self.require_active()?;
1433        let frame = self.frames.last_mut().unwrap();
1434
1435        match &frame.tracker {
1436            Tracker::Uninit => {
1437                // that's good, let's initialize it
1438            }
1439            Tracker::Init => {
1440                // initialized (perhaps from a previous round?) but should be a list tracker, let's fix that:
1441                frame.tracker = Tracker::List {
1442                    is_initialized: true,
1443                    current_child: false,
1444                };
1445                return Ok(self);
1446            }
1447            Tracker::List { is_initialized, .. } => {
1448                if *is_initialized {
1449                    // already initialized, nothing to do
1450                    return Ok(self);
1451                }
1452            }
1453            Tracker::SmartPointerSlice { .. } => {
1454                // begin_list is kinda superfluous when we're in a SmartPointerSlice state
1455                return Ok(self);
1456            }
1457            _ => {
1458                return Err(ReflectError::UnexpectedTracker {
1459                    message: "begin_list called but tracker isn't something list-like",
1460                    current_tracker: frame.tracker.kind(),
1461                });
1462            }
1463        };
1464
1465        // Check that we have a List
1466        let list_def = match &frame.shape.def {
1467            Def::List(list_def) => list_def,
1468            _ => {
1469                return Err(ReflectError::OperationFailed {
1470                    shape: frame.shape,
1471                    operation: "begin_list can only be called on List types",
1472                });
1473            }
1474        };
1475
1476        // Check that we have init_in_place_with_capacity function
1477        let init_fn = match list_def.vtable.init_in_place_with_capacity {
1478            Some(f) => f,
1479            None => {
1480                return Err(ReflectError::OperationFailed {
1481                    shape: frame.shape,
1482                    operation: "list type does not support initialization with capacity",
1483                });
1484            }
1485        };
1486
1487        // Initialize the list with default capacity (0)
1488        unsafe {
1489            init_fn(frame.data, 0);
1490        }
1491
1492        // Update tracker to List state
1493        frame.tracker = Tracker::List {
1494            is_initialized: true,
1495            current_child: false,
1496        };
1497
1498        Ok(self)
1499    }
1500
1501    /// Begins a map initialization operation
1502    /// This initializes the map with default capacity and allows inserting key-value pairs
1503    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
1504        self.require_active()?;
1505        let frame = self.frames.last_mut().unwrap();
1506
1507        // Check that we have a Map
1508        let map_def = match &frame.shape.def {
1509            Def::Map(map_def) => map_def,
1510            _ => {
1511                return Err(ReflectError::OperationFailed {
1512                    shape: frame.shape,
1513                    operation: "begin_map can only be called on Map types",
1514                });
1515            }
1516        };
1517
1518        // Check that we have init_in_place_with_capacity function
1519        let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1520
1521        // Initialize the map with default capacity (0)
1522        unsafe {
1523            init_fn(frame.data, 0);
1524        }
1525
1526        // Update tracker to Map state
1527        frame.tracker = Tracker::Map {
1528            is_initialized: true,
1529            insert_state: MapInsertState::Idle,
1530        };
1531
1532        Ok(self)
1533    }
1534
1535    /// Pushes a frame for the map key
1536    /// Automatically starts a new insert if we're idle
1537    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
1538        self.require_active()?;
1539        let frame = self.frames.last_mut().unwrap();
1540
1541        // Check that we have a Map and set up for key insertion
1542        let map_def = match (&frame.shape.def, &mut frame.tracker) {
1543            (
1544                Def::Map(map_def),
1545                Tracker::Map {
1546                    is_initialized: true,
1547                    insert_state,
1548                },
1549            ) => {
1550                match insert_state {
1551                    MapInsertState::Idle => {
1552                        // Start a new insert automatically
1553                        *insert_state = MapInsertState::PushingKey { key_ptr: None };
1554                    }
1555                    MapInsertState::PushingKey { key_ptr } => {
1556                        if key_ptr.is_some() {
1557                            return Err(ReflectError::OperationFailed {
1558                                shape: frame.shape,
1559                                operation: "already pushing a key, call end() first",
1560                            });
1561                        }
1562                    }
1563                    _ => {
1564                        return Err(ReflectError::OperationFailed {
1565                            shape: frame.shape,
1566                            operation: "must complete current operation before begin_key()",
1567                        });
1568                    }
1569                }
1570                map_def
1571            }
1572            _ => {
1573                return Err(ReflectError::OperationFailed {
1574                    shape: frame.shape,
1575                    operation: "must call begin_map() before begin_key()",
1576                });
1577            }
1578        };
1579
1580        // Get the key shape
1581        let key_shape = map_def.k();
1582
1583        // Allocate space for the key
1584        let key_layout = match key_shape.layout.sized_layout() {
1585            Ok(layout) => layout,
1586            Err(_) => {
1587                return Err(ReflectError::Unsized {
1588                    shape: key_shape,
1589                    operation: "begin_key allocating key",
1590                });
1591            }
1592        };
1593        let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1594
1595        if key_ptr_raw.is_null() {
1596            return Err(ReflectError::OperationFailed {
1597                shape: frame.shape,
1598                operation: "failed to allocate memory for map key",
1599            });
1600        }
1601
1602        // Store the key pointer in the insert state
1603        match &mut frame.tracker {
1604            Tracker::Map {
1605                insert_state: MapInsertState::PushingKey { key_ptr: kp },
1606                ..
1607            } => {
1608                *kp = Some(PtrUninit::new(key_ptr_raw));
1609            }
1610            _ => unreachable!(),
1611        }
1612
1613        // Push a new frame for the key
1614        self.frames.push(Frame::new(
1615            PtrUninit::new(key_ptr_raw),
1616            key_shape,
1617            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
1618        ));
1619
1620        Ok(self)
1621    }
1622
1623    /// Pushes a frame for the map value
1624    /// Must be called after the key has been set and popped
1625    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
1626        self.require_active()?;
1627        let frame = self.frames.last_mut().unwrap();
1628
1629        // Check that we have a Map in PushingValue state
1630        let map_def = match (&frame.shape.def, &mut frame.tracker) {
1631            (
1632                Def::Map(map_def),
1633                Tracker::Map {
1634                    insert_state: MapInsertState::PushingValue { value_ptr, .. },
1635                    ..
1636                },
1637            ) => {
1638                if value_ptr.is_some() {
1639                    return Err(ReflectError::OperationFailed {
1640                        shape: frame.shape,
1641                        operation: "already pushing a value, call pop() first",
1642                    });
1643                }
1644                map_def
1645            }
1646            _ => {
1647                return Err(ReflectError::OperationFailed {
1648                    shape: frame.shape,
1649                    operation: "must complete key before push_value()",
1650                });
1651            }
1652        };
1653
1654        // Get the value shape
1655        let value_shape = map_def.v();
1656
1657        // Allocate space for the value
1658        let value_layout = match value_shape.layout.sized_layout() {
1659            Ok(layout) => layout,
1660            Err(_) => {
1661                return Err(ReflectError::Unsized {
1662                    shape: value_shape,
1663                    operation: "begin_value allocating value",
1664                });
1665            }
1666        };
1667        let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1668
1669        if value_ptr_raw.is_null() {
1670            return Err(ReflectError::OperationFailed {
1671                shape: frame.shape,
1672                operation: "failed to allocate memory for map value",
1673            });
1674        }
1675
1676        // Store the value pointer in the insert state
1677        match &mut frame.tracker {
1678            Tracker::Map {
1679                insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1680                ..
1681            } => {
1682                *vp = Some(PtrUninit::new(value_ptr_raw));
1683            }
1684            _ => unreachable!(),
1685        }
1686
1687        // Push a new frame for the value
1688        self.frames.push(Frame::new(
1689            PtrUninit::new(value_ptr_raw),
1690            value_shape,
1691            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
1692        ));
1693
1694        Ok(self)
1695    }
1696
1697    /// Pushes an element to the list
1698    /// The element should be set using `set()` or similar methods, then `pop()` to complete
1699    pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
1700        crate::trace!("begin_list_item()");
1701        self.require_active()?;
1702        let frame = self.frames.last_mut().unwrap();
1703
1704        // Check if we're building a smart pointer slice
1705        if let Tracker::SmartPointerSlice {
1706            building_item,
1707            vtable: _,
1708        } = &frame.tracker
1709        {
1710            if *building_item {
1711                return Err(ReflectError::OperationFailed {
1712                    shape: frame.shape,
1713                    operation: "already building an item, call end() first",
1714                });
1715            }
1716
1717            // Get the element type from the smart pointer's pointee
1718            let element_shape = match &frame.shape.def {
1719                Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1720                    Some(pointee_shape) => match &pointee_shape.ty {
1721                        Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1722                        _ => {
1723                            return Err(ReflectError::OperationFailed {
1724                                shape: frame.shape,
1725                                operation: "smart pointer pointee is not a slice",
1726                            });
1727                        }
1728                    },
1729                    None => {
1730                        return Err(ReflectError::OperationFailed {
1731                            shape: frame.shape,
1732                            operation: "smart pointer has no pointee",
1733                        });
1734                    }
1735                },
1736                _ => {
1737                    return Err(ReflectError::OperationFailed {
1738                        shape: frame.shape,
1739                        operation: "expected smart pointer definition",
1740                    });
1741                }
1742            };
1743
1744            // Allocate space for the element
1745            crate::trace!("Pointee is a slice of {element_shape}");
1746            let element_layout = match element_shape.layout.sized_layout() {
1747                Ok(layout) => layout,
1748                Err(_) => {
1749                    return Err(ReflectError::OperationFailed {
1750                        shape: element_shape,
1751                        operation: "cannot allocate unsized element",
1752                    });
1753                }
1754            };
1755
1756            let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1757            if element_ptr.is_null() {
1758                alloc::alloc::handle_alloc_error(element_layout);
1759            }
1760
1761            // Create and push the element frame
1762            crate::trace!("Pushing element frame, which we just allocated");
1763            let element_frame = Frame::new(
1764                PtrUninit::new(element_ptr),
1765                element_shape,
1766                FrameOwnership::Owned,
1767            );
1768            self.frames.push(element_frame);
1769
1770            // Mark that we're building an item
1771            // We need to update the tracker after pushing the frame
1772            let parent_idx = self.frames.len() - 2;
1773            if let Tracker::SmartPointerSlice { building_item, .. } =
1774                &mut self.frames[parent_idx].tracker
1775            {
1776                crate::trace!("Marking element frame as building item");
1777                *building_item = true;
1778            }
1779
1780            return Ok(self);
1781        }
1782
1783        // Check that we have a List that's been initialized
1784        let list_def = match &frame.shape.def {
1785            Def::List(list_def) => list_def,
1786            _ => {
1787                return Err(ReflectError::OperationFailed {
1788                    shape: frame.shape,
1789                    operation: "push can only be called on List types",
1790                });
1791            }
1792        };
1793
1794        // Verify the tracker is in List state and initialized
1795        match &mut frame.tracker {
1796            Tracker::List {
1797                is_initialized: true,
1798                current_child,
1799            } => {
1800                if *current_child {
1801                    return Err(ReflectError::OperationFailed {
1802                        shape: frame.shape,
1803                        operation: "already pushing an element, call pop() first",
1804                    });
1805                }
1806                *current_child = true;
1807            }
1808            _ => {
1809                return Err(ReflectError::OperationFailed {
1810                    shape: frame.shape,
1811                    operation: "must call begin_list() before push()",
1812                });
1813            }
1814        }
1815
1816        // Get the element shape
1817        let element_shape = list_def.t();
1818
1819        // Allocate space for the new element
1820        let element_layout = match element_shape.layout.sized_layout() {
1821            Ok(layout) => layout,
1822            Err(_) => {
1823                return Err(ReflectError::Unsized {
1824                    shape: element_shape,
1825                    operation: "begin_list_item: calculating element layout",
1826                });
1827            }
1828        };
1829        let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1830
1831        if element_ptr.is_null() {
1832            return Err(ReflectError::OperationFailed {
1833                shape: frame.shape,
1834                operation: "failed to allocate memory for list element",
1835            });
1836        }
1837
1838        // Push a new frame for the element
1839        self.frames.push(Frame::new(
1840            PtrUninit::new(element_ptr),
1841            element_shape,
1842            FrameOwnership::Owned,
1843        ));
1844
1845        Ok(self)
1846    }
1847
1848    /// Pops the current frame off the stack, indicating we're done initializing the current field
1849    pub fn end(&mut self) -> Result<&mut Self, ReflectError> {
1850        crate::trace!("end() called");
1851        self.require_active()?;
1852
1853        // Special handling for SmartPointerSlice - convert builder to Arc
1854        if self.frames.len() == 1 {
1855            if let Tracker::SmartPointerSlice {
1856                vtable,
1857                building_item,
1858            } = &self.frames[0].tracker
1859            {
1860                if *building_item {
1861                    return Err(ReflectError::OperationFailed {
1862                        shape: self.frames[0].shape,
1863                        operation: "still building an item, finish it first",
1864                    });
1865                }
1866
1867                // Convert the builder to Arc<[T]>
1868                let builder_ptr = unsafe { self.frames[0].data.assume_init() };
1869                let arc_ptr = unsafe { (vtable.convert_fn)(builder_ptr) };
1870
1871                // Update the frame to store the Arc
1872                self.frames[0].data = PtrUninit::new(arc_ptr.as_byte_ptr() as *mut u8);
1873                self.frames[0].tracker = Tracker::Init;
1874                // The builder memory has been consumed by convert_fn, so we no longer own it
1875                self.frames[0].ownership = FrameOwnership::ManagedElsewhere;
1876
1877                return Ok(self);
1878            }
1879        }
1880
1881        if self.frames.len() <= 1 {
1882            // Never pop the last/root frame.
1883            return Err(ReflectError::InvariantViolation {
1884                invariant: "Partial::end() called with only one frame on the stack",
1885            });
1886        }
1887
1888        // Require that the top frame is fully initialized before popping.
1889        {
1890            let frame = self.frames.last().unwrap();
1891            trace!(
1892                "end(): Checking full initialization for frame with shape {} and tracker {:?}",
1893                frame.shape,
1894                frame.tracker.kind()
1895            );
1896            frame.require_full_initialization()?
1897        }
1898
1899        // Pop the frame and save its data pointer for SmartPointer handling
1900        let popped_frame = self.frames.pop().unwrap();
1901
1902        // Update parent frame's tracking when popping from a child
1903        let parent_frame = self.frames.last_mut().unwrap();
1904
1905        trace!(
1906            "end(): Popped {} (tracker {:?}), Parent {} (tracker {:?})",
1907            popped_frame.shape,
1908            popped_frame.tracker.kind(),
1909            parent_frame.shape,
1910            parent_frame.tracker.kind()
1911        );
1912
1913        // Check if we need to do a conversion - this happens when:
1914        // 1. The parent frame has an inner type that matches the popped frame's shape
1915        // 2. The parent frame has try_from
1916        // 3. The parent frame is not yet initialized
1917        let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
1918            && parent_frame.shape.inner.is_some()
1919            && parent_frame.shape.inner.unwrap()() == popped_frame.shape
1920            && parent_frame
1921                .shape
1922                .vtable
1923                .sized()
1924                .and_then(|v| (v.try_from)())
1925                .is_some();
1926
1927        if needs_conversion {
1928            trace!(
1929                "Detected implicit conversion needed from {} to {}",
1930                popped_frame.shape, parent_frame.shape
1931            );
1932            // Perform the conversion
1933            if let Some(try_from_fn) = parent_frame
1934                .shape
1935                .vtable
1936                .sized()
1937                .and_then(|v| (v.try_from)())
1938            {
1939                let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
1940                let inner_shape = popped_frame.shape;
1941
1942                trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
1943                let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
1944
1945                if let Err(e) = result {
1946                    trace!("Conversion failed: {e:?}");
1947
1948                    // Deallocate the inner value's memory since conversion failed
1949                    if let FrameOwnership::Owned = popped_frame.ownership {
1950                        if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1951                            if layout.size() > 0 {
1952                                trace!(
1953                                    "Deallocating conversion frame memory after failure: size={}, align={}",
1954                                    layout.size(),
1955                                    layout.align()
1956                                );
1957                                unsafe {
1958                                    alloc::alloc::dealloc(
1959                                        popped_frame.data.as_mut_byte_ptr(),
1960                                        layout,
1961                                    );
1962                                }
1963                            }
1964                        }
1965                    }
1966
1967                    return Err(ReflectError::TryFromError {
1968                        src_shape: inner_shape,
1969                        dst_shape: parent_frame.shape,
1970                        inner: e,
1971                    });
1972                }
1973
1974                trace!("Conversion succeeded, marking parent as initialized");
1975                parent_frame.tracker = Tracker::Init;
1976
1977                // Deallocate the inner value's memory since try_from consumed it
1978                if let FrameOwnership::Owned = popped_frame.ownership {
1979                    if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1980                        if layout.size() > 0 {
1981                            trace!(
1982                                "Deallocating conversion frame memory: size={}, align={}",
1983                                layout.size(),
1984                                layout.align()
1985                            );
1986                            unsafe {
1987                                alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
1988                            }
1989                        }
1990                    }
1991                }
1992
1993                return Ok(self);
1994            }
1995        }
1996
1997        match &mut parent_frame.tracker {
1998            Tracker::Struct {
1999                iset,
2000                current_child,
2001            } => {
2002                if let Some(idx) = *current_child {
2003                    iset.set(idx);
2004                    *current_child = None;
2005                }
2006            }
2007            Tracker::Array {
2008                iset,
2009                current_child,
2010            } => {
2011                if let Some(idx) = *current_child {
2012                    iset.set(idx);
2013                    *current_child = None;
2014                }
2015            }
2016            Tracker::SmartPointer { is_initialized } => {
2017                // We just popped the inner value frame, so now we need to create the smart pointer
2018                if let Def::Pointer(smart_ptr_def) = parent_frame.shape.def {
2019                    if let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn {
2020                        // The child frame contained the inner value
2021                        let inner_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
2022
2023                        // Use new_into_fn to create the Box
2024                        unsafe {
2025                            new_into_fn(parent_frame.data, inner_ptr);
2026                        }
2027
2028                        // Deallocate the inner value's memory since new_into_fn moved it
2029                        if let FrameOwnership::Owned = popped_frame.ownership {
2030                            if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2031                                if layout.size() > 0 {
2032                                    unsafe {
2033                                        alloc::alloc::dealloc(
2034                                            popped_frame.data.as_mut_byte_ptr(),
2035                                            layout,
2036                                        );
2037                                    }
2038                                }
2039                            }
2040                        }
2041
2042                        *is_initialized = true;
2043                    } else {
2044                        return Err(ReflectError::OperationFailed {
2045                            shape: parent_frame.shape,
2046                            operation: "SmartPointer missing new_into_fn",
2047                        });
2048                    }
2049                }
2050            }
2051            Tracker::Enum {
2052                data,
2053                current_child,
2054                ..
2055            } => {
2056                if let Some(idx) = *current_child {
2057                    data.set(idx);
2058                    *current_child = None;
2059                }
2060            }
2061            Tracker::List {
2062                is_initialized: true,
2063                current_child,
2064            } => {
2065                if *current_child {
2066                    // We just popped an element frame, now push it to the list
2067                    if let Def::List(list_def) = parent_frame.shape.def {
2068                        if let Some(push_fn) = list_def.vtable.push {
2069                            // The child frame contained the element value
2070                            let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
2071
2072                            // Use push to add element to the list
2073                            unsafe {
2074                                push_fn(
2075                                    PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
2076                                    element_ptr,
2077                                );
2078                            }
2079
2080                            // Deallocate the element's memory since push moved it
2081                            if let FrameOwnership::Owned = popped_frame.ownership {
2082                                if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2083                                    if layout.size() > 0 {
2084                                        unsafe {
2085                                            alloc::alloc::dealloc(
2086                                                popped_frame.data.as_mut_byte_ptr(),
2087                                                layout,
2088                                            );
2089                                        }
2090                                    }
2091                                }
2092                            }
2093
2094                            *current_child = false;
2095                        } else {
2096                            return Err(ReflectError::OperationFailed {
2097                                shape: parent_frame.shape,
2098                                operation: "List missing push function",
2099                            });
2100                        }
2101                    }
2102                }
2103            }
2104            Tracker::Map {
2105                is_initialized: true,
2106                insert_state,
2107            } => {
2108                match insert_state {
2109                    MapInsertState::PushingKey { key_ptr } => {
2110                        // We just popped the key frame
2111                        if let Some(key_ptr) = key_ptr {
2112                            // Transition to PushingValue state
2113                            *insert_state = MapInsertState::PushingValue {
2114                                key_ptr: *key_ptr,
2115                                value_ptr: None,
2116                            };
2117                        }
2118                    }
2119                    MapInsertState::PushingValue { key_ptr, value_ptr } => {
2120                        // We just popped the value frame, now insert the pair
2121                        if let (Some(value_ptr), Def::Map(map_def)) =
2122                            (value_ptr, parent_frame.shape.def)
2123                        {
2124                            let insert_fn = map_def.vtable.insert_fn;
2125
2126                            // Use insert to add key-value pair to the map
2127                            unsafe {
2128                                insert_fn(
2129                                    PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
2130                                    PtrMut::new(key_ptr.as_mut_byte_ptr()),
2131                                    PtrMut::new(value_ptr.as_mut_byte_ptr()),
2132                                );
2133                            }
2134
2135                            // Note: We don't deallocate the key and value memory here.
2136                            // The insert function has semantically moved the values into the map,
2137                            // but we still need to deallocate the temporary buffers.
2138                            // However, since we don't have frames for them anymore (they were popped),
2139                            // we need to handle deallocation here.
2140                            if let Ok(key_shape) = map_def.k().layout.sized_layout() {
2141                                if key_shape.size() > 0 {
2142                                    unsafe {
2143                                        alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
2144                                    }
2145                                }
2146                            }
2147                            if let Ok(value_shape) = map_def.v().layout.sized_layout() {
2148                                if value_shape.size() > 0 {
2149                                    unsafe {
2150                                        alloc::alloc::dealloc(
2151                                            value_ptr.as_mut_byte_ptr(),
2152                                            value_shape,
2153                                        );
2154                                    }
2155                                }
2156                            }
2157
2158                            // Reset to idle state
2159                            *insert_state = MapInsertState::Idle;
2160                        }
2161                    }
2162                    MapInsertState::Idle => {
2163                        // Nothing to do
2164                    }
2165                }
2166            }
2167            Tracker::Option { building_inner } => {
2168                // We just popped the inner value frame for an Option's Some variant
2169                if *building_inner {
2170                    if let Def::Option(option_def) = parent_frame.shape.def {
2171                        // Use the Option vtable to initialize Some(inner_value)
2172                        let init_some_fn = option_def.vtable.init_some_fn;
2173
2174                        // The popped frame contains the inner value
2175                        let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
2176
2177                        // Initialize the Option as Some(inner_value)
2178                        unsafe {
2179                            init_some_fn(parent_frame.data, inner_value_ptr);
2180                        }
2181
2182                        // Deallocate the inner value's memory since init_some_fn moved it
2183                        if let FrameOwnership::Owned = popped_frame.ownership {
2184                            if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2185                                if layout.size() > 0 {
2186                                    unsafe {
2187                                        alloc::alloc::dealloc(
2188                                            popped_frame.data.as_mut_byte_ptr(),
2189                                            layout,
2190                                        );
2191                                    }
2192                                }
2193                            }
2194                        }
2195
2196                        // Mark that we're no longer building the inner value
2197                        *building_inner = false;
2198                    } else {
2199                        return Err(ReflectError::OperationFailed {
2200                            shape: parent_frame.shape,
2201                            operation: "Option frame without Option definition",
2202                        });
2203                    }
2204                }
2205            }
2206            Tracker::Uninit | Tracker::Init => {
2207                match popped_frame.tracker {
2208                    Tracker::SmartPointerStr { is_initialized } => {
2209                        if !is_initialized {
2210                            return Err(ReflectError::InvariantViolation {
2211                                invariant: "popping smart pointer str without initializing it",
2212                            });
2213                        }
2214
2215                        // if the just-popped frame was a SmartPointerStr, we have some conversion to do:
2216                        // Special-case: SmartPointer<str> (Box<str>, Arc<str>, Rc<str>) via SmartPointerStr tracker
2217                        // Here, popped_frame actually contains a value for String that should be moved into the smart pointer.
2218                        // We convert the String into Box<str>, Arc<str>, or Rc<str> as appropriate and write it to the parent frame.
2219                        use alloc::{rc::Rc, string::String, sync::Arc};
2220                        let parent_shape = parent_frame.shape;
2221
2222                        if let Def::Pointer(smart_ptr_def) = parent_shape.def {
2223                            if let Some(known) = smart_ptr_def.known {
2224                                // Before doing anything: if the parent is init, we must drop what's inside,
2225                                // because we're about to replace it
2226                                if matches!(parent_frame.tracker, Tracker::Init) {
2227                                    if let Some(drop_fn) = parent_frame
2228                                        .shape
2229                                        .vtable
2230                                        .sized()
2231                                        .and_then(|v| (v.drop_in_place)())
2232                                    {
2233                                        unsafe { drop_fn(parent_frame.data.assume_init()) };
2234                                    }
2235                                    parent_frame.tracker = Tracker::Uninit;
2236                                }
2237
2238                                // The popped_frame (child) must be a Tracker::SmartPointerStr (checked above)
2239                                // Interpret the memory as a String, then convert and write.
2240                                let string_ptr = popped_frame.data.as_mut_byte_ptr() as *mut String;
2241                                let string_value = unsafe { core::ptr::read(string_ptr) };
2242
2243                                match known {
2244                                    KnownPointer::Box => {
2245                                        let boxed: Box<str> = string_value.into_boxed_str();
2246                                        unsafe {
2247                                            core::ptr::write(
2248                                                parent_frame.data.as_mut_byte_ptr()
2249                                                    as *mut Box<str>,
2250                                                boxed,
2251                                            );
2252                                        }
2253                                    }
2254                                    KnownPointer::Arc => {
2255                                        let arc: Arc<str> =
2256                                            Arc::from(string_value.into_boxed_str());
2257                                        unsafe {
2258                                            core::ptr::write(
2259                                                parent_frame.data.as_mut_byte_ptr()
2260                                                    as *mut Arc<str>,
2261                                                arc,
2262                                            );
2263                                        }
2264                                    }
2265                                    KnownPointer::Rc => {
2266                                        let rc: Rc<str> = Rc::from(string_value.into_boxed_str());
2267                                        unsafe {
2268                                            core::ptr::write(
2269                                                parent_frame.data.as_mut_byte_ptr() as *mut Rc<str>,
2270                                                rc,
2271                                            );
2272                                        }
2273                                    }
2274                                    _ => {}
2275                                }
2276                                parent_frame.tracker = Tracker::Init;
2277
2278                                // Now, deallocate temporary String allocation if necessary
2279                                if let FrameOwnership::Owned = popped_frame.ownership {
2280                                    if let Ok(layout) = String::SHAPE.layout.sized_layout() {
2281                                        if layout.size() > 0 {
2282                                            unsafe {
2283                                                alloc::alloc::dealloc(
2284                                                    popped_frame.data.as_mut_byte_ptr(),
2285                                                    layout,
2286                                                )
2287                                            };
2288                                        }
2289                                    }
2290                                }
2291                            } else {
2292                                return Err(ReflectError::OperationFailed {
2293                                    shape: parent_shape,
2294                                    operation: "SmartPointerStr for unknown smart pointer kind",
2295                                });
2296                            }
2297                        }
2298                    }
2299                    _ => {
2300                        return Err(ReflectError::OperationFailed {
2301                            shape: parent_frame.shape,
2302                            operation: "end()-ing a frame but the parent is Init/Uninit, that's... confusing?",
2303                        });
2304                    }
2305                }
2306            }
2307            Tracker::SmartPointerSlice {
2308                vtable,
2309                building_item,
2310            } => {
2311                if *building_item {
2312                    // We just popped an element frame, now push it to the slice builder
2313                    let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
2314
2315                    // Use the slice builder's push_fn to add the element
2316                    crate::trace!("Pushing element to slice builder");
2317                    unsafe {
2318                        let parent_ptr = parent_frame.data.assume_init();
2319                        (vtable.push_fn)(parent_ptr, element_ptr);
2320                    }
2321
2322                    // Deallocate the element's memory since push_fn moved it
2323                    if let FrameOwnership::Owned = popped_frame.ownership {
2324                        if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2325                            if layout.size() > 0 {
2326                                unsafe {
2327                                    alloc::alloc::dealloc(
2328                                        popped_frame.data.as_mut_byte_ptr(),
2329                                        layout,
2330                                    );
2331                                }
2332                            }
2333                        }
2334                    }
2335
2336                    if let Tracker::SmartPointerSlice {
2337                        building_item: bi, ..
2338                    } = &mut parent_frame.tracker
2339                    {
2340                        *bi = false;
2341                    }
2342                }
2343            }
2344            _ => {}
2345        }
2346
2347        Ok(self)
2348    }
2349
2350    /// Builds the value
2351    pub fn build(&mut self) -> Result<HeapValue<'facet>, ReflectError> {
2352        self.require_active()?;
2353        if self.frames.len() != 1 {
2354            self.state = PartialState::BuildFailed;
2355            return Err(ReflectError::InvariantViolation {
2356                invariant: "Partial::build() expects a single frame — call end() until that's the case",
2357            });
2358        }
2359
2360        let frame = self.frames.pop().unwrap();
2361
2362        // Check initialization before proceeding
2363        if let Err(e) = frame.require_full_initialization() {
2364            // Put the frame back so Drop can handle cleanup properly
2365            self.frames.push(frame);
2366            self.state = PartialState::BuildFailed;
2367            return Err(e);
2368        }
2369
2370        // Check invariants if present
2371        if let Some(invariants_fn) = frame.shape.vtable.sized().and_then(|v| (v.invariants)()) {
2372            // Safety: The value is fully initialized at this point (we just checked with require_full_initialization)
2373            let value_ptr = unsafe { frame.data.assume_init().as_const() };
2374            let invariants_ok = unsafe { invariants_fn(value_ptr) };
2375
2376            if !invariants_ok {
2377                // Put the frame back so Drop can handle cleanup properly
2378                self.frames.push(frame);
2379                self.state = PartialState::BuildFailed;
2380                return Err(ReflectError::InvariantViolation {
2381                    invariant: "Type invariants check failed",
2382                });
2383            }
2384        }
2385
2386        // Mark as built to prevent reuse
2387        self.state = PartialState::Built;
2388
2389        match frame
2390            .shape
2391            .layout
2392            .sized_layout()
2393            .map_err(|_layout_err| ReflectError::Unsized {
2394                shape: frame.shape,
2395                operation: "build (final check for sized layout)",
2396            }) {
2397            Ok(layout) => Ok(HeapValue {
2398                guard: Some(Guard {
2399                    ptr: frame.data.as_mut_byte_ptr(),
2400                    layout,
2401                }),
2402                shape: frame.shape,
2403                phantom: PhantomData,
2404            }),
2405            Err(e) => {
2406                // Put the frame back for proper cleanup
2407                self.frames.push(frame);
2408                self.state = PartialState::BuildFailed;
2409                Err(e)
2410            }
2411        }
2412    }
2413
2414    /// Returns a human-readable path representing the current traversal in the builder,
2415    /// e.g., `RootStruct.fieldName[index].subfield`.
2416    pub fn path(&self) -> String {
2417        let mut out = String::new();
2418
2419        let mut path_components = Vec::new();
2420        // The stack of enum/struct/sequence names currently in context.
2421        // Start from root and build upwards.
2422        for (i, frame) in self.frames.iter().enumerate() {
2423            match frame.shape.ty {
2424                Type::User(user_type) => match user_type {
2425                    UserType::Struct(struct_type) => {
2426                        // Try to get currently active field index
2427                        let mut field_str = None;
2428                        if let Tracker::Struct {
2429                            current_child: Some(idx),
2430                            ..
2431                        } = &frame.tracker
2432                        {
2433                            if let Some(field) = struct_type.fields.get(*idx) {
2434                                field_str = Some(field.name);
2435                            }
2436                        }
2437                        if i == 0 {
2438                            // Use Display for the root struct shape
2439                            path_components.push(format!("{}", frame.shape));
2440                        }
2441                        if let Some(field_name) = field_str {
2442                            path_components.push(format!(".{field_name}"));
2443                        }
2444                    }
2445                    UserType::Enum(_enum_type) => {
2446                        // Try to get currently active variant and field
2447                        if let Tracker::Enum {
2448                            variant,
2449                            current_child,
2450                            ..
2451                        } = &frame.tracker
2452                        {
2453                            if i == 0 {
2454                                // Use Display for the root enum shape
2455                                path_components.push(format!("{}", frame.shape));
2456                            }
2457                            path_components.push(format!("::{}", variant.name));
2458                            if let Some(idx) = *current_child {
2459                                if let Some(field) = variant.data.fields.get(idx) {
2460                                    path_components.push(format!(".{}", field.name));
2461                                }
2462                            }
2463                        } else if i == 0 {
2464                            // just the enum display
2465                            path_components.push(format!("{}", frame.shape));
2466                        }
2467                    }
2468                    UserType::Union(_union_type) => {
2469                        path_components.push(format!("{}", frame.shape));
2470                    }
2471                    UserType::Opaque => {
2472                        path_components.push("<opaque>".to_string());
2473                    }
2474                },
2475                Type::Sequence(seq_type) => match seq_type {
2476                    facet_core::SequenceType::Array(_array_def) => {
2477                        // Try to show current element index
2478                        if let Tracker::Array {
2479                            current_child: Some(idx),
2480                            ..
2481                        } = &frame.tracker
2482                        {
2483                            path_components.push(format!("[{idx}]"));
2484                        }
2485                    }
2486                    // You can add more for Slice, Vec, etc., if applicable
2487                    _ => {
2488                        // just indicate "[]" for sequence
2489                        path_components.push("[]".to_string());
2490                    }
2491                },
2492                Type::Pointer(_) => {
2493                    // Indicate deref
2494                    path_components.push("*".to_string());
2495                }
2496                _ => {
2497                    // No structural path
2498                }
2499            }
2500        }
2501        // Merge the path_components into a single string
2502        for component in path_components {
2503            out.push_str(&component);
2504        }
2505        out
2506    }
2507
2508    /// Returns the shape of the current frame.
2509    #[inline]
2510    pub fn shape(&self) -> &'static Shape {
2511        self.frames
2512            .last()
2513            .expect("Partial always has at least one frame")
2514            .shape
2515    }
2516
2517    /// Returns the innermost shape (alias for shape(), for compatibility)
2518    #[inline]
2519    pub fn innermost_shape(&self) -> &'static Shape {
2520        self.shape()
2521    }
2522
2523    /// Check if a struct field at the given index has been set
2524    pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
2525        let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
2526
2527        match &frame.tracker {
2528            Tracker::Uninit => Ok(false),
2529            Tracker::Init => Ok(true),
2530            Tracker::Struct { iset, .. } => Ok(iset.get(index)),
2531            Tracker::Enum { data, .. } => {
2532                // Check if the field is already marked as set
2533                if data.get(index) {
2534                    return Ok(true);
2535                }
2536
2537                // For enum variant fields that are empty structs, they are always initialized
2538                if let Tracker::Enum { variant, .. } = &frame.tracker {
2539                    if let Some(field) = variant.data.fields.get(index) {
2540                        if let Type::User(UserType::Struct(field_struct)) = field.shape.ty {
2541                            if field_struct.fields.is_empty() {
2542                                return Ok(true);
2543                            }
2544                        }
2545                    }
2546                }
2547
2548                Ok(false)
2549            }
2550            Tracker::Option { building_inner } => {
2551                // For Options, index 0 represents the inner value
2552                if index == 0 {
2553                    Ok(!building_inner)
2554                } else {
2555                    Err(ReflectError::InvalidOperation {
2556                        operation: "is_field_set",
2557                        reason: "Option only has one field (index 0)",
2558                    })
2559                }
2560            }
2561            _ => Err(ReflectError::InvalidOperation {
2562                operation: "is_field_set",
2563                reason: "Current frame is not a struct, enum variant, or option",
2564            }),
2565        }
2566    }
2567
2568    /// Find the index of a field by name in the current struct
2569    pub fn field_index(&self, field_name: &str) -> Option<usize> {
2570        let frame = self.frames.last()?;
2571
2572        match frame.shape.ty {
2573            Type::User(UserType::Struct(struct_def)) => {
2574                struct_def.fields.iter().position(|f| f.name == field_name)
2575            }
2576            Type::User(UserType::Enum(_)) => {
2577                // If we're in an enum variant, check its fields
2578                if let Tracker::Enum { variant, .. } = &frame.tracker {
2579                    variant
2580                        .data
2581                        .fields
2582                        .iter()
2583                        .position(|f| f.name == field_name)
2584                } else {
2585                    None
2586                }
2587            }
2588            _ => None,
2589        }
2590    }
2591
2592    /// Get the currently selected variant for an enum
2593    pub fn selected_variant(&self) -> Option<Variant> {
2594        let frame = self.frames.last()?;
2595
2596        match &frame.tracker {
2597            Tracker::Enum { variant, .. } => Some(**variant),
2598            _ => None,
2599        }
2600    }
2601
2602    /// Find a variant by name in the current enum
2603    pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'static Variant)> {
2604        let frame = self.frames.last()?;
2605
2606        if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
2607            enum_def
2608                .variants
2609                .iter()
2610                .enumerate()
2611                .find(|(_, v)| v.name == variant_name)
2612        } else {
2613            None
2614        }
2615    }
2616
2617    /// Begin building the Some variant of an Option
2618    pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
2619        self.require_active()?;
2620        let frame = self.frames.last_mut().unwrap();
2621
2622        // Verify we're working with an Option
2623        let option_def = match frame.shape.def {
2624            Def::Option(def) => def,
2625            _ => {
2626                return Err(ReflectError::WasNotA {
2627                    expected: "Option",
2628                    actual: frame.shape,
2629                });
2630            }
2631        };
2632
2633        // Initialize the tracker for Option building
2634        if matches!(frame.tracker, Tracker::Uninit) {
2635            frame.tracker = Tracker::Option {
2636                building_inner: true,
2637            };
2638        }
2639
2640        // Get the inner type shape
2641        let inner_shape = option_def.t;
2642
2643        // Allocate memory for the inner value
2644        let inner_layout =
2645            inner_shape
2646                .layout
2647                .sized_layout()
2648                .map_err(|_| ReflectError::Unsized {
2649                    shape: inner_shape,
2650                    operation: "begin_some, allocating Option inner value",
2651                })?;
2652
2653        let inner_data = if inner_layout.size() == 0 {
2654            // For ZST, use a non-null but unallocated pointer
2655            PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2656        } else {
2657            // Allocate memory for the inner value
2658            let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2659            if ptr.is_null() {
2660                alloc::alloc::handle_alloc_error(inner_layout);
2661            }
2662            PtrUninit::new(ptr)
2663        };
2664
2665        // Create a new frame for the inner value
2666        let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
2667        self.frames.push(inner_frame);
2668
2669        Ok(self)
2670    }
2671
2672    /// Begin building the inner value of a wrapper type
2673    pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
2674        self.require_active()?;
2675
2676        // Get the inner shape and check for try_from
2677        let (inner_shape, has_try_from, parent_shape) = {
2678            let frame = self.frames.last().unwrap();
2679            if let Some(inner_fn) = frame.shape.inner {
2680                let inner_shape = inner_fn();
2681                let has_try_from = frame
2682                    .shape
2683                    .vtable
2684                    .sized()
2685                    .and_then(|v| (v.try_from)())
2686                    .is_some();
2687                (Some(inner_shape), has_try_from, frame.shape)
2688            } else {
2689                (None, false, frame.shape)
2690            }
2691        };
2692
2693        if let Some(inner_shape) = inner_shape {
2694            if has_try_from {
2695                // Create a conversion frame with the inner shape
2696
2697                // For conversion frames, we leave the parent tracker unchanged
2698                // This allows automatic conversion detection to work properly
2699
2700                // Allocate memory for the inner value (conversion source)
2701                let inner_layout =
2702                    inner_shape
2703                        .layout
2704                        .sized_layout()
2705                        .map_err(|_| ReflectError::Unsized {
2706                            shape: inner_shape,
2707                            operation: "begin_inner, getting inner layout",
2708                        })?;
2709
2710                let inner_data = if inner_layout.size() == 0 {
2711                    // For ZST, use a non-null but unallocated pointer
2712                    PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2713                } else {
2714                    // Allocate memory for the inner value
2715                    let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2716                    if ptr.is_null() {
2717                        alloc::alloc::handle_alloc_error(inner_layout);
2718                    }
2719                    PtrUninit::new(ptr)
2720                };
2721
2722                // For conversion frames, we create a frame directly with the inner shape
2723                // This allows setting values of the inner type which will be converted
2724                // The automatic conversion detection in end() will handle the conversion
2725                trace!(
2726                    "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
2727                );
2728                self.frames
2729                    .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
2730
2731                Ok(self)
2732            } else {
2733                // For wrapper types without try_from, navigate to the first field
2734                // This is a common pattern for newtype wrappers
2735                trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
2736                self.begin_nth_field(0)
2737            }
2738        } else {
2739            Err(ReflectError::OperationFailed {
2740                shape: parent_shape,
2741                operation: "type does not have an inner value",
2742            })
2743        }
2744    }
2745
2746    /// Copy a value from a Peek into the current position (safe alternative to set_shape)
2747    pub fn set_from_peek(&mut self, peek: &Peek<'_, '_>) -> Result<&mut Self, ReflectError> {
2748        self.require_active()?;
2749
2750        // Get the source value's pointer and shape
2751        let src_ptr = peek.data();
2752        let src_shape = peek.shape();
2753
2754        // Safety: This is a safe wrapper around set_shape
2755        // The peek guarantees the source data is valid for its shape
2756        unsafe { self.set_shape(src_ptr.thin().unwrap(), src_shape) }
2757    }
2758
2759    /// Copy a field from a struct's default value (safe wrapper for deserialization)
2760    /// This method creates the Peek internally to avoid exposing unsafe code to callers
2761    pub fn set_field_from_default(
2762        &mut self,
2763        field_data: PtrConst<'_>,
2764        field_shape: &'static Shape,
2765    ) -> Result<&mut Self, ReflectError> {
2766        self.require_active()?;
2767
2768        // Safety: The caller guarantees that field_data points to valid data for field_shape
2769        // This is typically used when copying default values during deserialization
2770        unsafe { self.set_shape(field_data, field_shape) }
2771    }
2772
2773    /// Fill all unset fields from the struct's default value
2774    /// This is a safe API for format deserializers that forbid unsafe code
2775    pub fn fill_unset_fields_from_default(&mut self) -> Result<&mut Self, ReflectError> {
2776        self.require_active()?;
2777
2778        let frame = self.frames.last().unwrap();
2779        let shape = frame.shape;
2780
2781        // Check if this is a struct with the default attribute
2782        if !shape.has_default_attr() {
2783            return Ok(self);
2784        }
2785
2786        // Make sure we're working with a struct
2787        let struct_def = match shape.ty {
2788            Type::User(UserType::Struct(sd)) => sd,
2789            _ => return Ok(self), // Not a struct, nothing to do
2790        };
2791
2792        // Check if any fields are unset
2793        let mut has_unset = false;
2794        for index in 0..struct_def.fields.len() {
2795            if !self.is_field_set(index)? {
2796                has_unset = true;
2797                break;
2798            }
2799        }
2800
2801        if !has_unset {
2802            return Ok(self); // All fields are set, nothing to do
2803        }
2804
2805        // Create a default instance
2806        let default_val = Partial::alloc_shape(shape)?.set_default()?.build()?;
2807        let peek = default_val.peek();
2808
2809        // Convert to struct peek
2810        let struct_peek = peek
2811            .into_struct()
2812            .map_err(|_| ReflectError::OperationFailed {
2813                shape,
2814                operation: "expected struct peek for default value",
2815            })?;
2816
2817        // Copy unset fields from the default
2818        for (index, _field) in struct_def.fields.iter().enumerate() {
2819            if !self.is_field_set(index)? {
2820                self.begin_nth_field(index)?;
2821
2822                // Get the field from the default value
2823                let def_field =
2824                    struct_peek
2825                        .field(index)
2826                        .map_err(|_| ReflectError::OperationFailed {
2827                            shape,
2828                            operation: "failed to get field from default struct",
2829                        })?;
2830
2831                self.set_from_peek(&def_field)?;
2832                self.end()?;
2833            }
2834        }
2835
2836        Ok(self)
2837    }
2838
2839    /// Convenience shortcut: sets the nth element of an array directly to value, popping after.
2840    pub fn set_nth_element<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2841    where
2842        U: Facet<'facet>,
2843    {
2844        self.begin_nth_element(idx)?.set(value)?.end()
2845    }
2846
2847    /// Convenience shortcut: sets the field at index `idx` directly to value, popping after.
2848    pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2849    where
2850        U: Facet<'facet>,
2851    {
2852        self.begin_nth_field(idx)?.set(value)?.end()
2853    }
2854
2855    /// Convenience shortcut: sets the named field to value, popping after.
2856    pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
2857    where
2858        U: Facet<'facet>,
2859    {
2860        self.begin_field(field_name)?.set(value)?.end()
2861    }
2862
2863    /// Convenience shortcut: sets the nth field of an enum variant directly to value, popping after.
2864    pub fn set_nth_enum_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
2865    where
2866        U: Facet<'facet>,
2867    {
2868        self.begin_nth_enum_field(idx)?.set(value)?.end()
2869    }
2870
2871    /// Convenience shortcut: sets the key for a map key-value insertion, then pops after.
2872    pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2873    where
2874        U: Facet<'facet>,
2875    {
2876        self.begin_key()?.set(value)?.end()
2877    }
2878
2879    /// Convenience shortcut: sets the value for a map key-value insertion, then pops after.
2880    pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2881    where
2882        U: Facet<'facet>,
2883    {
2884        self.begin_value()?.set(value)?.end()
2885    }
2886
2887    /// Shorthand for: begin_list_item(), set, end
2888    pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2889    where
2890        U: Facet<'facet>,
2891    {
2892        self.begin_list_item()?.set(value)?.end()
2893    }
2894}
2895
2896/// A typed wrapper around `Partial`, for when you want to statically
2897/// ensure that `build` gives you the proper type.
2898pub struct TypedPartial<'facet, T> {
2899    inner: Partial<'facet>,
2900    phantom: PhantomData<T>,
2901}
2902
2903impl<'facet, T> TypedPartial<'facet, T> {
2904    /// Unwraps the underlying Partial, consuming self.
2905    pub fn inner_mut(&mut self) -> &mut Partial<'facet> {
2906        &mut self.inner
2907    }
2908
2909    /// Builds the value and returns a `Box<T>`
2910    pub fn build(&mut self) -> Result<Box<T>, ReflectError>
2911    where
2912        T: Facet<'facet>,
2913    {
2914        trace!(
2915            "TypedPartial::build: Building value for type {} which should == {}",
2916            T::SHAPE,
2917            self.inner.shape()
2918        );
2919        let heap_value = self.inner.build()?;
2920        trace!(
2921            "TypedPartial::build: Built heap value with shape: {}",
2922            heap_value.shape()
2923        );
2924        // Safety: HeapValue was constructed from T and the shape layout is correct.
2925        let result = unsafe { heap_value.into_box_unchecked::<T>() };
2926        trace!("TypedPartial::build: Successfully converted to Box<T>");
2927        Ok(result)
2928    }
2929
2930    /// Sets a value wholesale into the current frame
2931    pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
2932    where
2933        U: Facet<'facet>,
2934    {
2935        self.inner.set(value)?;
2936        Ok(self)
2937    }
2938
2939    /// Sets a value into the current frame by shape, for shape-based operations
2940    pub fn set_shape(
2941        &mut self,
2942        src_value: PtrConst<'_>,
2943        src_shape: &'static Shape,
2944    ) -> Result<&mut Self, ReflectError> {
2945        unsafe { self.inner.set_shape(src_value, src_shape)? };
2946        Ok(self)
2947    }
2948
2949    /// See [Partial::begin_field]
2950    pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
2951        self.inner.begin_field(field_name)?;
2952        Ok(self)
2953    }
2954
2955    /// See [Partial::begin_nth_field]
2956    pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
2957        self.inner.begin_nth_field(idx)?;
2958        Ok(self)
2959    }
2960
2961    /// See [Partial::begin_nth_element]
2962    pub fn begin_nth_element(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
2963        self.inner.begin_nth_element(idx)?;
2964        Ok(self)
2965    }
2966
2967    /// See [Partial::begin_smart_ptr]
2968    pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
2969        self.inner.begin_smart_ptr()?;
2970        Ok(self)
2971    }
2972
2973    /// See [Partial::end]
2974    pub fn end(&mut self) -> Result<&mut Self, ReflectError> {
2975        self.inner.end()?;
2976        Ok(self)
2977    }
2978
2979    /// See [Partial::set_default]
2980    pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
2981        self.inner.set_default()?;
2982        Ok(self)
2983    }
2984
2985    /// See [Partial::set_from_function]
2986    pub fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
2987    where
2988        F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
2989    {
2990        self.inner.set_from_function(f)?;
2991        Ok(self)
2992    }
2993
2994    /// See [Partial::parse_from_str]
2995    pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
2996        self.inner.parse_from_str(s)?;
2997        Ok(self)
2998    }
2999
3000    /// See [Partial::select_variant]
3001    pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
3002        self.inner.select_variant(discriminant)?;
3003        Ok(self)
3004    }
3005
3006    /// See [Partial::select_variant_named]
3007    pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
3008        self.inner.select_variant_named(variant_name)?;
3009        Ok(self)
3010    }
3011
3012    /// See [Partial::select_nth_variant] to the inner partial instance.
3013    pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
3014        self.inner.select_nth_variant(index)?;
3015        Ok(self)
3016    }
3017
3018    /// See [Partial::begin_nth_enum_field] to the inner partial instance.
3019    pub fn begin_nth_enum_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
3020        self.inner.begin_nth_enum_field(idx)?;
3021        Ok(self)
3022    }
3023
3024    /// See [Partial::begin_list]
3025    pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
3026        self.inner.begin_list()?;
3027        Ok(self)
3028    }
3029
3030    /// See [Partial::begin_list_item]
3031    pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
3032        self.inner.begin_list_item()?;
3033        Ok(self)
3034    }
3035
3036    /// See [Partial::begin_map]
3037    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
3038        self.inner.begin_map()?;
3039        Ok(self)
3040    }
3041
3042    /// See [Partial::begin_key]
3043    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
3044        self.inner.begin_key()?;
3045        Ok(self)
3046    }
3047
3048    /// See [Partial::begin_value]
3049    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
3050        self.inner.begin_value()?;
3051        Ok(self)
3052    }
3053
3054    /// Returns a human-readable path representing the current traversal in the builder,
3055    /// e.g., `RootStruct.fieldName[index].subfield`.
3056    pub fn path(&self) -> String {
3057        self.inner.path()
3058    }
3059
3060    /// Returns the shape of the current frame.
3061    pub fn shape(&self) -> &'static Shape {
3062        self.inner.shape()
3063    }
3064
3065    /// Convenience shortcut: sets the nth element of an array directly to value, popping after.
3066    pub fn set_nth_element<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
3067    where
3068        U: Facet<'facet>,
3069    {
3070        self.inner.set_nth_element(idx, value)?;
3071        Ok(self)
3072    }
3073
3074    /// Convenience shortcut: sets the field at index `idx` directly to value, popping after.
3075    pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
3076    where
3077        U: Facet<'facet>,
3078    {
3079        self.inner.set_nth_field(idx, value)?;
3080        Ok(self)
3081    }
3082
3083    /// Convenience shortcut: sets the named field to value, popping after.
3084    pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
3085    where
3086        U: Facet<'facet>,
3087    {
3088        self.inner.set_field(field_name, value)?;
3089        Ok(self)
3090    }
3091
3092    /// Convenience shortcut: sets the nth field of an enum variant directly to value, popping after.
3093    pub fn set_nth_enum_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
3094    where
3095        U: Facet<'facet>,
3096    {
3097        self.inner.set_nth_enum_field(idx, value)?;
3098        Ok(self)
3099    }
3100
3101    /// Convenience shortcut: sets the key for a map key-value insertion, then pops after.
3102    pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
3103    where
3104        U: Facet<'facet>,
3105    {
3106        self.inner.set_key(value)?;
3107        Ok(self)
3108    }
3109
3110    /// Convenience shortcut: sets the value for a map key-value insertion, then pops after.
3111    pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
3112    where
3113        U: Facet<'facet>,
3114    {
3115        self.inner.set_value(value)?;
3116        Ok(self)
3117    }
3118
3119    /// Shorthand for: begin_list_item(), set(), end(), useful when pushing a scalar
3120    pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
3121    where
3122        U: Facet<'facet>,
3123    {
3124        self.inner.push(value)?;
3125        Ok(self)
3126    }
3127
3128    /// Begin building the `Some` variant of an `Option`
3129    pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
3130        self.inner.begin_some()?;
3131        Ok(self)
3132    }
3133
3134    /// Begin building the inner value of a wrapper type
3135    pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
3136        self.inner.begin_inner()?;
3137        Ok(self)
3138    }
3139}
3140
3141impl<'facet, T> core::fmt::Debug for TypedPartial<'facet, T> {
3142    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3143        f.debug_struct("TypedPartial")
3144            .field("shape", &self.inner.frames.last().map(|frame| frame.shape))
3145            .finish()
3146    }
3147}
3148
3149impl<'facet> Drop for Partial<'facet> {
3150    fn drop(&mut self) {
3151        trace!("🧹 Partial is being dropped");
3152
3153        // We need to properly drop all initialized fields
3154        while let Some(frame) = self.frames.pop() {
3155            match &frame.tracker {
3156                Tracker::Uninit => {
3157                    // Nothing was initialized, nothing to drop
3158                }
3159                Tracker::Init => {
3160                    // Fully initialized, drop it
3161                    if let Some(drop_fn) =
3162                        frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3163                    {
3164                        unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3165                    }
3166                }
3167                Tracker::Array { iset, .. } => {
3168                    // Drop initialized array elements
3169                    if let Type::Sequence(facet_core::SequenceType::Array(array_def)) =
3170                        frame.shape.ty
3171                    {
3172                        let element_layout = array_def.t.layout.sized_layout().ok();
3173                        if let Some(layout) = element_layout {
3174                            for idx in 0..array_def.n {
3175                                if iset.get(idx) {
3176                                    let offset = layout.size() * idx;
3177                                    let element_ptr = unsafe { frame.data.field_init_at(offset) };
3178                                    if let Some(drop_fn) =
3179                                        array_def.t.vtable.sized().and_then(|v| (v.drop_in_place)())
3180                                    {
3181                                        unsafe { drop_fn(element_ptr) };
3182                                    }
3183                                }
3184                            }
3185                        }
3186                    }
3187                }
3188                Tracker::Struct { iset, .. } => {
3189                    // Drop initialized struct fields
3190                    if let Type::User(UserType::Struct(struct_type)) = frame.shape.ty {
3191                        for (idx, field) in struct_type.fields.iter().enumerate() {
3192                            if iset.get(idx) {
3193                                // This field was initialized, drop it
3194                                let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
3195                                if let Some(drop_fn) =
3196                                    field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3197                                {
3198                                    unsafe { drop_fn(field_ptr) };
3199                                }
3200                            }
3201                        }
3202                    }
3203                }
3204                Tracker::Enum { variant, data, .. } => {
3205                    // Drop initialized enum variant fields
3206                    for (idx, field) in variant.data.fields.iter().enumerate() {
3207                        if data.get(idx) {
3208                            // This field was initialized, drop it
3209                            let field_ptr =
3210                                unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
3211                            if let Some(drop_fn) =
3212                                field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3213                            {
3214                                unsafe { drop_fn(PtrMut::new(field_ptr)) };
3215                            }
3216                        }
3217                    }
3218                }
3219                Tracker::SmartPointer { is_initialized } => {
3220                    // Drop the initialized Box
3221                    if *is_initialized {
3222                        if let Some(drop_fn) =
3223                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3224                        {
3225                            unsafe { drop_fn(frame.data.assume_init()) };
3226                        }
3227                    }
3228                    // Note: we don't deallocate the inner value here because
3229                    // the Box's drop will handle that
3230                }
3231                Tracker::SmartPointerStr { is_initialized } => {
3232                    // Drop the initialized string
3233                    if *is_initialized {
3234                        if let Some(drop_fn) =
3235                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3236                        {
3237                            unsafe { drop_fn(frame.data.assume_init()) };
3238                        }
3239                    }
3240                }
3241                Tracker::SmartPointerSlice { vtable, .. } => {
3242                    // Free the slice builder
3243                    let builder_ptr = unsafe { frame.data.assume_init() };
3244                    unsafe {
3245                        (vtable.free_fn)(builder_ptr);
3246                    }
3247                }
3248                Tracker::List { is_initialized, .. } => {
3249                    // Drop the initialized List
3250                    if *is_initialized {
3251                        if let Some(drop_fn) =
3252                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3253                        {
3254                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3255                        }
3256                    }
3257                }
3258                Tracker::Map {
3259                    is_initialized,
3260                    insert_state,
3261                } => {
3262                    // Drop the initialized Map
3263                    if *is_initialized {
3264                        if let Some(drop_fn) =
3265                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3266                        {
3267                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3268                        }
3269                    }
3270
3271                    // Clean up any in-progress insertion state
3272                    match insert_state {
3273                        MapInsertState::PushingKey { key_ptr } => {
3274                            if let Some(key_ptr) = key_ptr {
3275                                // Deallocate the key buffer
3276                                if let Def::Map(map_def) = frame.shape.def {
3277                                    if let Ok(key_shape) = map_def.k().layout.sized_layout() {
3278                                        if key_shape.size() > 0 {
3279                                            unsafe {
3280                                                alloc::alloc::dealloc(
3281                                                    key_ptr.as_mut_byte_ptr(),
3282                                                    key_shape,
3283                                                )
3284                                            };
3285                                        }
3286                                    }
3287                                }
3288                            }
3289                        }
3290                        MapInsertState::PushingValue { key_ptr, value_ptr } => {
3291                            // Drop and deallocate both key and value buffers
3292                            if let Def::Map(map_def) = frame.shape.def {
3293                                // Drop and deallocate the key
3294                                if let Some(drop_fn) =
3295                                    map_def.k().vtable.sized().and_then(|v| (v.drop_in_place)())
3296                                {
3297                                    unsafe { drop_fn(PtrMut::new(key_ptr.as_mut_byte_ptr())) };
3298                                }
3299                                if let Ok(key_shape) = map_def.k().layout.sized_layout() {
3300                                    if key_shape.size() > 0 {
3301                                        unsafe {
3302                                            alloc::alloc::dealloc(
3303                                                key_ptr.as_mut_byte_ptr(),
3304                                                key_shape,
3305                                            )
3306                                        };
3307                                    }
3308                                }
3309
3310                                // Drop and deallocate the value if it exists
3311                                if let Some(value_ptr) = value_ptr {
3312                                    if let Ok(value_shape) = map_def.v().layout.sized_layout() {
3313                                        if value_shape.size() > 0 {
3314                                            unsafe {
3315                                                alloc::alloc::dealloc(
3316                                                    value_ptr.as_mut_byte_ptr(),
3317                                                    value_shape,
3318                                                )
3319                                            };
3320                                        }
3321                                    }
3322                                }
3323                            }
3324                        }
3325                        MapInsertState::Idle => {}
3326                    }
3327                }
3328                Tracker::Option { building_inner } => {
3329                    // If we're building the inner value, it will be handled by the Option vtable
3330                    // No special cleanup needed here as the Option will either be properly
3331                    // initialized or remain uninitialized
3332                    if !building_inner {
3333                        // Option is fully initialized, drop it normally
3334                        if let Some(drop_fn) =
3335                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3336                        {
3337                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3338                        }
3339                    }
3340                }
3341            }
3342
3343            // Only deallocate if this frame owns the allocation
3344            if let FrameOwnership::Owned = frame.ownership {
3345                if let Ok(layout) = frame.shape.layout.sized_layout() {
3346                    if layout.size() > 0 {
3347                        unsafe { alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout) };
3348                    }
3349                }
3350            }
3351        }
3352    }
3353}