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