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, KnownPointer, PtrConst, PtrMut, PtrUninit, Shape, SliceBuilderVTable,
130    Type, UserType, Variant,
131};
132use iset::ISet;
133
134/// State of a partial value
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136enum PartialState {
137    /// Partial is active and can be modified
138    Active,
139    /// Partial has been successfully built and cannot be reused
140    Built,
141    /// Building failed and Partial is poisoned
142    BuildFailed,
143}
144
145/// A work-in-progress heap-allocated value
146///
147/// # Lifetimes
148///
149/// * `'facet`: The lifetime of borrowed values within the structure (or 'static if it's owned)
150/// * `'shape`: The lifetime of the Shape structure itself (often 'static)
151pub struct Partial<'facet, '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::Pointer(smart_ptr_def) => {
1226                // Check for supported smart pointer types
1227                match smart_ptr_def.known {
1228                    Some(KnownPointer::Box)
1229                    | Some(KnownPointer::Rc)
1230                    | Some(KnownPointer::Arc)
1231                    | Some(KnownPointer::SharedReference) => {
1232                        // Supported types, continue
1233                    }
1234                    _ => {
1235                        return Err(ReflectError::OperationFailed {
1236                            shape: frame.shape,
1237                            operation: "only the following pointers are currently supported: Box<T>, Rc<T>, Arc<T>, and &T",
1238                        });
1239                    }
1240                }
1241
1242                // Get the pointee shape
1243                let pointee_shape = match smart_ptr_def.pointee() {
1244                    Some(shape) => shape,
1245                    None => {
1246                        return Err(ReflectError::OperationFailed {
1247                            shape: frame.shape,
1248                            operation: "Box must have a pointee shape",
1249                        });
1250                    }
1251                };
1252
1253                if pointee_shape.layout.sized_layout().is_ok() {
1254                    // pointee is sized, we can allocate it — for `Arc<T>` we'll be allocating a `T` and
1255                    // holding onto it. We'll build a new Arc with it when ending the smart pointer frame.
1256
1257                    if matches!(frame.tracker, Tracker::Uninit) {
1258                        frame.tracker = Tracker::SmartPointer {
1259                            is_initialized: false,
1260                        };
1261                    }
1262
1263                    let inner_layout = match pointee_shape.layout.sized_layout() {
1264                        Ok(layout) => layout,
1265                        Err(_) => {
1266                            return Err(ReflectError::Unsized {
1267                                shape: pointee_shape,
1268                                operation: "begin_smart_ptr, calculating inner value layout",
1269                            });
1270                        }
1271                    };
1272                    let inner_ptr: *mut u8 = unsafe { alloc::alloc::alloc(inner_layout) };
1273                    if inner_ptr.is_null() {
1274                        return Err(ReflectError::OperationFailed {
1275                            shape: frame.shape,
1276                            operation: "failed to allocate memory for smart pointer inner value",
1277                        });
1278                    }
1279
1280                    // Push a new frame for the inner value
1281                    self.frames.push(Frame::new(
1282                        PtrUninit::new(inner_ptr),
1283                        pointee_shape,
1284                        FrameOwnership::Owned,
1285                    ));
1286                } else {
1287                    // pointee is unsized, we only support a handful of cases there
1288                    if pointee_shape == str::SHAPE {
1289                        crate::trace!("Pointee is str");
1290                        // Allocate space for a String
1291                        let string_layout = String::SHAPE
1292                            .layout
1293                            .sized_layout()
1294                            .expect("String must have a sized layout");
1295                        let string_ptr: *mut u8 = unsafe { alloc::alloc::alloc(string_layout) };
1296                        if string_ptr.is_null() {
1297                            alloc::alloc::handle_alloc_error(string_layout);
1298                        }
1299                        let mut frame = Frame::new(
1300                            PtrUninit::new(string_ptr),
1301                            String::SHAPE,
1302                            FrameOwnership::Owned,
1303                        );
1304                        frame.tracker = Tracker::SmartPointerStr;
1305                        self.frames.push(frame);
1306                    } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
1307                        crate::trace!("Pointee is [{}]", _st.t);
1308
1309                        // Get the slice builder vtable
1310                        let slice_builder_vtable = smart_ptr_def
1311                            .vtable
1312                            .slice_builder_vtable
1313                            .ok_or(ReflectError::OperationFailed {
1314                                shape: frame.shape,
1315                                operation: "smart pointer does not support slice building",
1316                            })?;
1317
1318                        // Create a new builder
1319                        let builder_ptr = (slice_builder_vtable.new_fn)();
1320
1321                        // Deallocate the original Arc allocation before replacing with slice builder
1322                        if let FrameOwnership::Owned = frame.ownership {
1323                            if let Ok(layout) = frame.shape.layout.sized_layout() {
1324                                if layout.size() > 0 {
1325                                    unsafe {
1326                                        alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
1327                                    };
1328                                }
1329                            }
1330                        }
1331
1332                        // Update the current frame to use the slice builder
1333                        frame.data = PtrUninit::new(builder_ptr.as_mut_byte_ptr());
1334                        frame.tracker = Tracker::SmartPointerSlice {
1335                            vtable: slice_builder_vtable,
1336                            building_item: false,
1337                        };
1338                        // The slice builder memory is managed by the vtable, not by us
1339                        frame.ownership = FrameOwnership::ManagedElsewhere;
1340                    } else {
1341                        todo!("unsupported unsize pointee shape: {}", pointee_shape)
1342                    }
1343                }
1344
1345                Ok(self)
1346            }
1347            _ => Err(ReflectError::OperationFailed {
1348                shape: frame.shape,
1349                operation: "push_smart_ptr can only be called on compatible types",
1350            }),
1351        }
1352    }
1353
1354    /// Begins a pushback operation for a list (Vec, etc.)
1355    /// This initializes the list with default capacity and allows pushing elements
1356    pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1357        crate::trace!("begin_list()");
1358        self.require_active()?;
1359        let frame = self.frames.last_mut().unwrap();
1360
1361        // Check if we're in a SmartPointerSlice state - if so, the list is already initialized
1362        if matches!(frame.tracker, Tracker::SmartPointerSlice { .. }) {
1363            crate::trace!(
1364                "begin_list is kinda superfluous when we're in a SmartPointerSlice state"
1365            );
1366            return Ok(self);
1367        }
1368
1369        // Check that we have a List
1370        let list_def = match &frame.shape.def {
1371            Def::List(list_def) => list_def,
1372            _ => {
1373                return Err(ReflectError::OperationFailed {
1374                    shape: frame.shape,
1375                    operation: "begin_pushback can only be called on List types",
1376                });
1377            }
1378        };
1379
1380        // Check that we have init_in_place_with_capacity function
1381        let init_fn = match list_def.vtable.init_in_place_with_capacity {
1382            Some(f) => f,
1383            None => {
1384                return Err(ReflectError::OperationFailed {
1385                    shape: frame.shape,
1386                    operation: "list type does not support initialization with capacity",
1387                });
1388            }
1389        };
1390
1391        // Initialize the list with default capacity (0)
1392        unsafe {
1393            init_fn(frame.data, 0);
1394        }
1395
1396        // Update tracker to List state
1397        frame.tracker = Tracker::List {
1398            is_initialized: true,
1399            current_child: false,
1400        };
1401
1402        Ok(self)
1403    }
1404
1405    /// Begins a map initialization operation
1406    /// This initializes the map with default capacity and allows inserting key-value pairs
1407    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1408        self.require_active()?;
1409        let frame = self.frames.last_mut().unwrap();
1410
1411        // Check that we have a Map
1412        let map_def = match &frame.shape.def {
1413            Def::Map(map_def) => map_def,
1414            _ => {
1415                return Err(ReflectError::OperationFailed {
1416                    shape: frame.shape,
1417                    operation: "begin_map can only be called on Map types",
1418                });
1419            }
1420        };
1421
1422        // Check that we have init_in_place_with_capacity function
1423        let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
1424
1425        // Initialize the map with default capacity (0)
1426        unsafe {
1427            init_fn(frame.data, 0);
1428        }
1429
1430        // Update tracker to Map state
1431        frame.tracker = Tracker::Map {
1432            is_initialized: true,
1433            insert_state: MapInsertState::Idle,
1434        };
1435
1436        Ok(self)
1437    }
1438
1439    /// Pushes a frame for the map key
1440    /// Automatically starts a new insert if we're idle
1441    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1442        self.require_active()?;
1443        let frame = self.frames.last_mut().unwrap();
1444
1445        // Check that we have a Map and set up for key insertion
1446        let map_def = match (&frame.shape.def, &mut frame.tracker) {
1447            (
1448                Def::Map(map_def),
1449                Tracker::Map {
1450                    is_initialized: true,
1451                    insert_state,
1452                },
1453            ) => {
1454                match insert_state {
1455                    MapInsertState::Idle => {
1456                        // Start a new insert automatically
1457                        *insert_state = MapInsertState::PushingKey { key_ptr: None };
1458                    }
1459                    MapInsertState::PushingKey { key_ptr } => {
1460                        if key_ptr.is_some() {
1461                            return Err(ReflectError::OperationFailed {
1462                                shape: frame.shape,
1463                                operation: "already pushing a key, call end() first",
1464                            });
1465                        }
1466                    }
1467                    _ => {
1468                        return Err(ReflectError::OperationFailed {
1469                            shape: frame.shape,
1470                            operation: "must complete current operation before begin_key()",
1471                        });
1472                    }
1473                }
1474                map_def
1475            }
1476            _ => {
1477                return Err(ReflectError::OperationFailed {
1478                    shape: frame.shape,
1479                    operation: "must call begin_map() before begin_key()",
1480                });
1481            }
1482        };
1483
1484        // Get the key shape
1485        let key_shape = map_def.k();
1486
1487        // Allocate space for the key
1488        let key_layout = match key_shape.layout.sized_layout() {
1489            Ok(layout) => layout,
1490            Err(_) => {
1491                return Err(ReflectError::Unsized {
1492                    shape: key_shape,
1493                    operation: "begin_key allocating key",
1494                });
1495            }
1496        };
1497        let key_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(key_layout) };
1498
1499        if key_ptr_raw.is_null() {
1500            return Err(ReflectError::OperationFailed {
1501                shape: frame.shape,
1502                operation: "failed to allocate memory for map key",
1503            });
1504        }
1505
1506        // Store the key pointer in the insert state
1507        match &mut frame.tracker {
1508            Tracker::Map {
1509                insert_state: MapInsertState::PushingKey { key_ptr: kp },
1510                ..
1511            } => {
1512                *kp = Some(PtrUninit::new(key_ptr_raw));
1513            }
1514            _ => unreachable!(),
1515        }
1516
1517        // Push a new frame for the key
1518        self.frames.push(Frame::new(
1519            PtrUninit::new(key_ptr_raw),
1520            key_shape,
1521            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
1522        ));
1523
1524        Ok(self)
1525    }
1526
1527    /// Pushes a frame for the map value
1528    /// Must be called after the key has been set and popped
1529    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1530        self.require_active()?;
1531        let frame = self.frames.last_mut().unwrap();
1532
1533        // Check that we have a Map in PushingValue state
1534        let map_def = match (&frame.shape.def, &mut frame.tracker) {
1535            (
1536                Def::Map(map_def),
1537                Tracker::Map {
1538                    insert_state: MapInsertState::PushingValue { value_ptr, .. },
1539                    ..
1540                },
1541            ) => {
1542                if value_ptr.is_some() {
1543                    return Err(ReflectError::OperationFailed {
1544                        shape: frame.shape,
1545                        operation: "already pushing a value, call pop() first",
1546                    });
1547                }
1548                map_def
1549            }
1550            _ => {
1551                return Err(ReflectError::OperationFailed {
1552                    shape: frame.shape,
1553                    operation: "must complete key before push_value()",
1554                });
1555            }
1556        };
1557
1558        // Get the value shape
1559        let value_shape = map_def.v();
1560
1561        // Allocate space for the value
1562        let value_layout = match value_shape.layout.sized_layout() {
1563            Ok(layout) => layout,
1564            Err(_) => {
1565                return Err(ReflectError::Unsized {
1566                    shape: value_shape,
1567                    operation: "begin_value allocating value",
1568                });
1569            }
1570        };
1571        let value_ptr_raw: *mut u8 = unsafe { alloc::alloc::alloc(value_layout) };
1572
1573        if value_ptr_raw.is_null() {
1574            return Err(ReflectError::OperationFailed {
1575                shape: frame.shape,
1576                operation: "failed to allocate memory for map value",
1577            });
1578        }
1579
1580        // Store the value pointer in the insert state
1581        match &mut frame.tracker {
1582            Tracker::Map {
1583                insert_state: MapInsertState::PushingValue { value_ptr: vp, .. },
1584                ..
1585            } => {
1586                *vp = Some(PtrUninit::new(value_ptr_raw));
1587            }
1588            _ => unreachable!(),
1589        }
1590
1591        // Push a new frame for the value
1592        self.frames.push(Frame::new(
1593            PtrUninit::new(value_ptr_raw),
1594            value_shape,
1595            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
1596        ));
1597
1598        Ok(self)
1599    }
1600
1601    /// Pushes an element to the list
1602    /// The element should be set using `set()` or similar methods, then `pop()` to complete
1603    pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1604        crate::trace!("begin_list_item()");
1605        self.require_active()?;
1606        let frame = self.frames.last_mut().unwrap();
1607
1608        // Check if we're building a smart pointer slice
1609        if let Tracker::SmartPointerSlice {
1610            building_item,
1611            vtable: _,
1612        } = &frame.tracker
1613        {
1614            if *building_item {
1615                return Err(ReflectError::OperationFailed {
1616                    shape: frame.shape,
1617                    operation: "already building an item, call end() first",
1618                });
1619            }
1620
1621            // Get the element type from the smart pointer's pointee
1622            let element_shape = match &frame.shape.def {
1623                Def::Pointer(smart_ptr_def) => match smart_ptr_def.pointee() {
1624                    Some(pointee_shape) => match &pointee_shape.ty {
1625                        Type::Sequence(SequenceType::Slice(slice_type)) => slice_type.t,
1626                        _ => {
1627                            return Err(ReflectError::OperationFailed {
1628                                shape: frame.shape,
1629                                operation: "smart pointer pointee is not a slice",
1630                            });
1631                        }
1632                    },
1633                    None => {
1634                        return Err(ReflectError::OperationFailed {
1635                            shape: frame.shape,
1636                            operation: "smart pointer has no pointee",
1637                        });
1638                    }
1639                },
1640                _ => {
1641                    return Err(ReflectError::OperationFailed {
1642                        shape: frame.shape,
1643                        operation: "expected smart pointer definition",
1644                    });
1645                }
1646            };
1647
1648            // Allocate space for the element
1649            crate::trace!("Pointee is a slice of {element_shape}");
1650            let element_layout = match element_shape.layout.sized_layout() {
1651                Ok(layout) => layout,
1652                Err(_) => {
1653                    return Err(ReflectError::OperationFailed {
1654                        shape: element_shape,
1655                        operation: "cannot allocate unsized element",
1656                    });
1657                }
1658            };
1659
1660            let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1661            if element_ptr.is_null() {
1662                alloc::alloc::handle_alloc_error(element_layout);
1663            }
1664
1665            // Create and push the element frame
1666            crate::trace!("Pushing element frame, which we just allocated");
1667            let element_frame = Frame::new(
1668                PtrUninit::new(element_ptr),
1669                element_shape,
1670                FrameOwnership::Owned,
1671            );
1672            self.frames.push(element_frame);
1673
1674            // Mark that we're building an item
1675            // We need to update the tracker after pushing the frame
1676            let parent_idx = self.frames.len() - 2;
1677            if let Tracker::SmartPointerSlice { building_item, .. } =
1678                &mut self.frames[parent_idx].tracker
1679            {
1680                crate::trace!("Marking element frame as building item");
1681                *building_item = true;
1682            }
1683
1684            return Ok(self);
1685        }
1686
1687        // Check that we have a List that's been initialized
1688        let list_def = match &frame.shape.def {
1689            Def::List(list_def) => list_def,
1690            _ => {
1691                return Err(ReflectError::OperationFailed {
1692                    shape: frame.shape,
1693                    operation: "push can only be called on List types",
1694                });
1695            }
1696        };
1697
1698        // Verify the tracker is in List state and initialized
1699        match &mut frame.tracker {
1700            Tracker::List {
1701                is_initialized: true,
1702                current_child,
1703            } => {
1704                if *current_child {
1705                    return Err(ReflectError::OperationFailed {
1706                        shape: frame.shape,
1707                        operation: "already pushing an element, call pop() first",
1708                    });
1709                }
1710                *current_child = true;
1711            }
1712            _ => {
1713                return Err(ReflectError::OperationFailed {
1714                    shape: frame.shape,
1715                    operation: "must call begin_pushback() before push()",
1716                });
1717            }
1718        }
1719
1720        // Get the element shape
1721        let element_shape = list_def.t();
1722
1723        // Allocate space for the new element
1724        let element_layout = match element_shape.layout.sized_layout() {
1725            Ok(layout) => layout,
1726            Err(_) => {
1727                return Err(ReflectError::Unsized {
1728                    shape: element_shape,
1729                    operation: "begin_list_item: calculating element layout",
1730                });
1731            }
1732        };
1733        let element_ptr: *mut u8 = unsafe { alloc::alloc::alloc(element_layout) };
1734
1735        if element_ptr.is_null() {
1736            return Err(ReflectError::OperationFailed {
1737                shape: frame.shape,
1738                operation: "failed to allocate memory for list element",
1739            });
1740        }
1741
1742        // Push a new frame for the element
1743        self.frames.push(Frame::new(
1744            PtrUninit::new(element_ptr),
1745            element_shape,
1746            FrameOwnership::Owned,
1747        ));
1748
1749        Ok(self)
1750    }
1751
1752    /// Pops the current frame off the stack, indicating we're done initializing the current field
1753    pub fn end(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
1754        crate::trace!("end() called");
1755        self.require_active()?;
1756
1757        // Special handling for SmartPointerSlice - convert builder to Arc
1758        if self.frames.len() == 1 {
1759            if let Tracker::SmartPointerSlice {
1760                vtable,
1761                building_item,
1762            } = &self.frames[0].tracker
1763            {
1764                if *building_item {
1765                    return Err(ReflectError::OperationFailed {
1766                        shape: self.frames[0].shape,
1767                        operation: "still building an item, finish it first",
1768                    });
1769                }
1770
1771                // Convert the builder to Arc<[T]>
1772                let builder_ptr = unsafe { self.frames[0].data.assume_init() };
1773                let arc_ptr = unsafe { (vtable.convert_fn)(builder_ptr) };
1774
1775                // Update the frame to store the Arc
1776                self.frames[0].data = PtrUninit::new(arc_ptr.as_byte_ptr() as *mut u8);
1777                self.frames[0].tracker = Tracker::Init;
1778                // The builder memory has been consumed by convert_fn, so we no longer own it
1779                self.frames[0].ownership = FrameOwnership::ManagedElsewhere;
1780
1781                return Ok(self);
1782            }
1783        }
1784
1785        if self.frames.len() <= 1 {
1786            // Never pop the last/root frame.
1787            return Err(ReflectError::InvariantViolation {
1788                invariant: "Partial::end() called with only one frame on the stack",
1789            });
1790        }
1791
1792        // Require that the top frame is fully initialized before popping.
1793        {
1794            let frame = self.frames.last().unwrap();
1795            trace!(
1796                "end(): Checking full initialization for frame with shape {}",
1797                frame.shape
1798            );
1799            frame.require_full_initialization()?
1800        }
1801
1802        // Pop the frame and save its data pointer for SmartPointer handling
1803        let popped_frame = self.frames.pop().unwrap();
1804        trace!(
1805            "end(): Popped frame with shape {}, tracker {:?}",
1806            popped_frame.shape, popped_frame.tracker
1807        );
1808
1809        // Update parent frame's tracking when popping from a child
1810        let parent_frame = self.frames.last_mut().unwrap();
1811
1812        trace!(
1813            "end(): Parent frame shape: {}, tracker: {:?}",
1814            parent_frame.shape, parent_frame.tracker
1815        );
1816
1817        // Check if we need to do a conversion - this happens when:
1818        // 1. The parent frame has an inner type that matches the popped frame's shape
1819        // 2. The parent frame has try_from
1820        // 3. The parent frame is not yet initialized
1821        let needs_conversion = matches!(parent_frame.tracker, Tracker::Uninit)
1822            && parent_frame.shape.inner.is_some()
1823            && parent_frame.shape.inner.unwrap()() == popped_frame.shape
1824            && parent_frame
1825                .shape
1826                .vtable
1827                .sized()
1828                .and_then(|v| (v.try_from)())
1829                .is_some();
1830
1831        if needs_conversion {
1832            trace!(
1833                "Detected implicit conversion needed from {} to {}",
1834                popped_frame.shape, parent_frame.shape
1835            );
1836            // Perform the conversion
1837            if let Some(try_from_fn) = parent_frame
1838                .shape
1839                .vtable
1840                .sized()
1841                .and_then(|v| (v.try_from)())
1842            {
1843                let inner_ptr = unsafe { popped_frame.data.assume_init().as_const() };
1844                let inner_shape = popped_frame.shape;
1845
1846                trace!("Converting from {} to {}", inner_shape, parent_frame.shape);
1847                let result = unsafe { try_from_fn(inner_ptr, inner_shape, parent_frame.data) };
1848
1849                if let Err(e) = result {
1850                    trace!("Conversion failed: {e:?}");
1851
1852                    // Deallocate the inner value's memory since conversion failed
1853                    if let FrameOwnership::Owned = popped_frame.ownership {
1854                        if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1855                            if layout.size() > 0 {
1856                                trace!(
1857                                    "Deallocating conversion frame memory after failure: size={}, align={}",
1858                                    layout.size(),
1859                                    layout.align()
1860                                );
1861                                unsafe {
1862                                    alloc::alloc::dealloc(
1863                                        popped_frame.data.as_mut_byte_ptr(),
1864                                        layout,
1865                                    );
1866                                }
1867                            }
1868                        }
1869                    }
1870
1871                    return Err(ReflectError::TryFromError {
1872                        src_shape: inner_shape,
1873                        dst_shape: parent_frame.shape,
1874                        inner: e,
1875                    });
1876                }
1877
1878                trace!("Conversion succeeded, marking parent as initialized");
1879                parent_frame.tracker = Tracker::Init;
1880
1881                // Deallocate the inner value's memory since try_from consumed it
1882                if let FrameOwnership::Owned = popped_frame.ownership {
1883                    if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1884                        if layout.size() > 0 {
1885                            trace!(
1886                                "Deallocating conversion frame memory: size={}, align={}",
1887                                layout.size(),
1888                                layout.align()
1889                            );
1890                            unsafe {
1891                                alloc::alloc::dealloc(popped_frame.data.as_mut_byte_ptr(), layout);
1892                            }
1893                        }
1894                    }
1895                }
1896
1897                return Ok(self);
1898            }
1899        }
1900
1901        match &mut parent_frame.tracker {
1902            Tracker::Struct {
1903                iset,
1904                current_child,
1905            } => {
1906                if let Some(idx) = *current_child {
1907                    iset.set(idx);
1908                    *current_child = None;
1909                }
1910            }
1911            Tracker::Array {
1912                iset,
1913                current_child,
1914            } => {
1915                if let Some(idx) = *current_child {
1916                    iset.set(idx);
1917                    *current_child = None;
1918                }
1919            }
1920            Tracker::SmartPointer { is_initialized } => {
1921                // We just popped the inner value frame, so now we need to create the smart pointer
1922                if let Def::Pointer(smart_ptr_def) = parent_frame.shape.def {
1923                    if let Some(new_into_fn) = smart_ptr_def.vtable.new_into_fn {
1924                        // The child frame contained the inner value
1925                        let inner_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
1926
1927                        // Use new_into_fn to create the Box
1928                        unsafe {
1929                            new_into_fn(parent_frame.data, inner_ptr);
1930                        }
1931
1932                        // Deallocate the inner value's memory since new_into_fn moved it
1933                        if let FrameOwnership::Owned = popped_frame.ownership {
1934                            if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1935                                if layout.size() > 0 {
1936                                    unsafe {
1937                                        alloc::alloc::dealloc(
1938                                            popped_frame.data.as_mut_byte_ptr(),
1939                                            layout,
1940                                        );
1941                                    }
1942                                }
1943                            }
1944                        }
1945
1946                        *is_initialized = true;
1947                    } else {
1948                        return Err(ReflectError::OperationFailed {
1949                            shape: parent_frame.shape,
1950                            operation: "SmartPointer missing new_into_fn",
1951                        });
1952                    }
1953                }
1954            }
1955            Tracker::Enum {
1956                data,
1957                current_child,
1958                ..
1959            } => {
1960                if let Some(idx) = *current_child {
1961                    data.set(idx);
1962                    *current_child = None;
1963                }
1964            }
1965            Tracker::List {
1966                is_initialized: true,
1967                current_child,
1968            } => {
1969                if *current_child {
1970                    // We just popped an element frame, now push it to the list
1971                    if let Def::List(list_def) = parent_frame.shape.def {
1972                        if let Some(push_fn) = list_def.vtable.push {
1973                            // The child frame contained the element value
1974                            let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
1975
1976                            // Use push to add element to the list
1977                            unsafe {
1978                                push_fn(
1979                                    PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
1980                                    element_ptr,
1981                                );
1982                            }
1983
1984                            // Deallocate the element's memory since push moved it
1985                            if let FrameOwnership::Owned = popped_frame.ownership {
1986                                if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
1987                                    if layout.size() > 0 {
1988                                        unsafe {
1989                                            alloc::alloc::dealloc(
1990                                                popped_frame.data.as_mut_byte_ptr(),
1991                                                layout,
1992                                            );
1993                                        }
1994                                    }
1995                                }
1996                            }
1997
1998                            *current_child = false;
1999                        } else {
2000                            return Err(ReflectError::OperationFailed {
2001                                shape: parent_frame.shape,
2002                                operation: "List missing push function",
2003                            });
2004                        }
2005                    }
2006                }
2007            }
2008            Tracker::Map {
2009                is_initialized: true,
2010                insert_state,
2011            } => {
2012                match insert_state {
2013                    MapInsertState::PushingKey { key_ptr } => {
2014                        // We just popped the key frame
2015                        if let Some(key_ptr) = key_ptr {
2016                            // Transition to PushingValue state
2017                            *insert_state = MapInsertState::PushingValue {
2018                                key_ptr: *key_ptr,
2019                                value_ptr: None,
2020                            };
2021                        }
2022                    }
2023                    MapInsertState::PushingValue { key_ptr, value_ptr } => {
2024                        // We just popped the value frame, now insert the pair
2025                        if let (Some(value_ptr), Def::Map(map_def)) =
2026                            (value_ptr, parent_frame.shape.def)
2027                        {
2028                            let insert_fn = map_def.vtable.insert_fn;
2029
2030                            // Use insert to add key-value pair to the map
2031                            unsafe {
2032                                insert_fn(
2033                                    PtrMut::new(parent_frame.data.as_mut_byte_ptr()),
2034                                    PtrMut::new(key_ptr.as_mut_byte_ptr()),
2035                                    PtrMut::new(value_ptr.as_mut_byte_ptr()),
2036                                );
2037                            }
2038
2039                            // Note: We don't deallocate the key and value memory here.
2040                            // The insert function has semantically moved the values into the map,
2041                            // but we still need to deallocate the temporary buffers.
2042                            // However, since we don't have frames for them anymore (they were popped),
2043                            // we need to handle deallocation here.
2044                            if let Ok(key_shape) = map_def.k().layout.sized_layout() {
2045                                if key_shape.size() > 0 {
2046                                    unsafe {
2047                                        alloc::alloc::dealloc(key_ptr.as_mut_byte_ptr(), key_shape);
2048                                    }
2049                                }
2050                            }
2051                            if let Ok(value_shape) = map_def.v().layout.sized_layout() {
2052                                if value_shape.size() > 0 {
2053                                    unsafe {
2054                                        alloc::alloc::dealloc(
2055                                            value_ptr.as_mut_byte_ptr(),
2056                                            value_shape,
2057                                        );
2058                                    }
2059                                }
2060                            }
2061
2062                            // Reset to idle state
2063                            *insert_state = MapInsertState::Idle;
2064                        }
2065                    }
2066                    MapInsertState::Idle => {
2067                        // Nothing to do
2068                    }
2069                }
2070            }
2071            Tracker::Option { building_inner } => {
2072                // We just popped the inner value frame for an Option's Some variant
2073                if *building_inner {
2074                    if let Def::Option(option_def) = parent_frame.shape.def {
2075                        // Use the Option vtable to initialize Some(inner_value)
2076                        let init_some_fn = option_def.vtable.init_some_fn;
2077
2078                        // The popped frame contains the inner value
2079                        let inner_value_ptr = unsafe { popped_frame.data.assume_init().as_const() };
2080
2081                        // Initialize the Option as Some(inner_value)
2082                        unsafe {
2083                            init_some_fn(parent_frame.data, inner_value_ptr);
2084                        }
2085
2086                        // Deallocate the inner value's memory since init_some_fn moved it
2087                        if let FrameOwnership::Owned = popped_frame.ownership {
2088                            if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2089                                if layout.size() > 0 {
2090                                    unsafe {
2091                                        alloc::alloc::dealloc(
2092                                            popped_frame.data.as_mut_byte_ptr(),
2093                                            layout,
2094                                        );
2095                                    }
2096                                }
2097                            }
2098                        }
2099
2100                        // Mark that we're no longer building the inner value
2101                        *building_inner = false;
2102                    } else {
2103                        return Err(ReflectError::OperationFailed {
2104                            shape: parent_frame.shape,
2105                            operation: "Option frame without Option definition",
2106                        });
2107                    }
2108                }
2109            }
2110            Tracker::Uninit => {
2111                // if the just-popped frame was a SmartPointerStr, we have some conversion to do:
2112                // Special-case: SmartPointer<str> (Box<str>, Arc<str>, Rc<str>) via SmartPointerStr tracker
2113                // Here, popped_frame actually contains a value for String that should be moved into the smart pointer.
2114                // We convert the String into Box<str>, Arc<str>, or Rc<str> as appropriate and write it to the parent frame.
2115                use alloc::{rc::Rc, string::String, sync::Arc};
2116                let parent_shape = parent_frame.shape;
2117                if let Def::Pointer(smart_ptr_def) = parent_shape.def {
2118                    if let Some(known) = smart_ptr_def.known {
2119                        // The popped_frame (child) must be a Tracker::SmartPointerStr (checked above)
2120                        // Interpret the memory as a String, then convert and write.
2121                        let string_ptr = popped_frame.data.as_mut_byte_ptr() as *mut String;
2122                        let string_value = unsafe { core::ptr::read(string_ptr) };
2123                        match known {
2124                            KnownPointer::Box => {
2125                                let boxed: Box<str> = string_value.into_boxed_str();
2126                                unsafe {
2127                                    core::ptr::write(
2128                                        parent_frame.data.as_mut_byte_ptr() as *mut Box<str>,
2129                                        boxed,
2130                                    );
2131                                }
2132                            }
2133                            KnownPointer::Arc => {
2134                                let arc: Arc<str> = Arc::from(string_value.into_boxed_str());
2135                                unsafe {
2136                                    core::ptr::write(
2137                                        parent_frame.data.as_mut_byte_ptr() as *mut Arc<str>,
2138                                        arc,
2139                                    );
2140                                }
2141                            }
2142                            KnownPointer::Rc => {
2143                                let rc: Rc<str> = Rc::from(string_value.into_boxed_str());
2144                                unsafe {
2145                                    core::ptr::write(
2146                                        parent_frame.data.as_mut_byte_ptr() as *mut Rc<str>,
2147                                        rc,
2148                                    );
2149                                }
2150                            }
2151                            _ => {}
2152                        }
2153                        parent_frame.tracker = Tracker::Init;
2154                        // Now, deallocate temporary String allocation if necessary
2155                        if let FrameOwnership::Owned = popped_frame.ownership {
2156                            if let Ok(layout) = String::SHAPE.layout.sized_layout() {
2157                                if layout.size() > 0 {
2158                                    unsafe {
2159                                        alloc::alloc::dealloc(
2160                                            popped_frame.data.as_mut_byte_ptr(),
2161                                            layout,
2162                                        )
2163                                    };
2164                                }
2165                            }
2166                        }
2167                    } else {
2168                        return Err(ReflectError::OperationFailed {
2169                            shape: parent_shape,
2170                            operation: "SmartPointerStr for unknown smart pointer kind",
2171                        });
2172                    }
2173                }
2174            }
2175            Tracker::SmartPointerSlice {
2176                vtable,
2177                building_item,
2178            } => {
2179                if *building_item {
2180                    // We just popped an element frame, now push it to the slice builder
2181                    let element_ptr = PtrMut::new(popped_frame.data.as_mut_byte_ptr());
2182
2183                    // Use the slice builder's push_fn to add the element
2184                    crate::trace!("Pushing element to slice builder");
2185                    unsafe {
2186                        let parent_ptr = parent_frame.data.assume_init();
2187                        (vtable.push_fn)(parent_ptr, element_ptr);
2188                    }
2189
2190                    // Deallocate the element's memory since push_fn moved it
2191                    if let FrameOwnership::Owned = popped_frame.ownership {
2192                        if let Ok(layout) = popped_frame.shape.layout.sized_layout() {
2193                            if layout.size() > 0 {
2194                                unsafe {
2195                                    alloc::alloc::dealloc(
2196                                        popped_frame.data.as_mut_byte_ptr(),
2197                                        layout,
2198                                    );
2199                                }
2200                            }
2201                        }
2202                    }
2203
2204                    if let Tracker::SmartPointerSlice {
2205                        building_item: bi, ..
2206                    } = &mut parent_frame.tracker
2207                    {
2208                        *bi = false;
2209                    }
2210                }
2211            }
2212            _ => {}
2213        }
2214
2215        Ok(self)
2216    }
2217
2218    /// Builds the value
2219    pub fn build(&mut self) -> Result<HeapValue<'facet, 'shape>, ReflectError<'shape>> {
2220        self.require_active()?;
2221        if self.frames.len() != 1 {
2222            self.state = PartialState::BuildFailed;
2223            return Err(ReflectError::InvariantViolation {
2224                invariant: "Partial::build() expects a single frame — pop until that's the case",
2225            });
2226        }
2227
2228        let frame = self.frames.pop().unwrap();
2229
2230        // Check initialization before proceeding
2231        if let Err(e) = frame.require_full_initialization() {
2232            // Put the frame back so Drop can handle cleanup properly
2233            self.frames.push(frame);
2234            self.state = PartialState::BuildFailed;
2235            return Err(e);
2236        }
2237
2238        // Check invariants if present
2239        if let Some(invariants_fn) = frame.shape.vtable.sized().and_then(|v| (v.invariants)()) {
2240            // Safety: The value is fully initialized at this point (we just checked with require_full_initialization)
2241            let value_ptr = unsafe { frame.data.assume_init().as_const() };
2242            let invariants_ok = unsafe { invariants_fn(value_ptr) };
2243
2244            if !invariants_ok {
2245                // Put the frame back so Drop can handle cleanup properly
2246                self.frames.push(frame);
2247                self.state = PartialState::BuildFailed;
2248                return Err(ReflectError::InvariantViolation {
2249                    invariant: "Type invariants check failed",
2250                });
2251            }
2252        }
2253
2254        // Mark as built to prevent reuse
2255        self.state = PartialState::Built;
2256
2257        match frame
2258            .shape
2259            .layout
2260            .sized_layout()
2261            .map_err(|_layout_err| ReflectError::Unsized {
2262                shape: frame.shape,
2263                operation: "build (final check for sized layout)",
2264            }) {
2265            Ok(layout) => Ok(HeapValue {
2266                guard: Some(Guard {
2267                    ptr: frame.data.as_mut_byte_ptr(),
2268                    layout,
2269                }),
2270                shape: frame.shape,
2271                phantom: PhantomData,
2272            }),
2273            Err(e) => {
2274                // Put the frame back for proper cleanup
2275                self.frames.push(frame);
2276                self.state = PartialState::BuildFailed;
2277                Err(e)
2278            }
2279        }
2280    }
2281
2282    /// Returns a human-readable path representing the current traversal in the builder,
2283    /// e.g., `RootStruct.fieldName[index].subfield`.
2284    pub fn path(&self) -> String {
2285        let mut out = String::new();
2286
2287        let mut path_components = Vec::new();
2288        // The stack of enum/struct/sequence names currently in context.
2289        // Start from root and build upwards.
2290        for (i, frame) in self.frames.iter().enumerate() {
2291            match frame.shape.ty {
2292                Type::User(user_type) => match user_type {
2293                    UserType::Struct(struct_type) => {
2294                        // Try to get currently active field index
2295                        let mut field_str = None;
2296                        if let Tracker::Struct {
2297                            current_child: Some(idx),
2298                            ..
2299                        } = &frame.tracker
2300                        {
2301                            if let Some(field) = struct_type.fields.get(*idx) {
2302                                field_str = Some(field.name);
2303                            }
2304                        }
2305                        if i == 0 {
2306                            // Use Display for the root struct shape
2307                            path_components.push(format!("{}", frame.shape));
2308                        }
2309                        if let Some(field_name) = field_str {
2310                            path_components.push(format!(".{field_name}"));
2311                        }
2312                    }
2313                    UserType::Enum(_enum_type) => {
2314                        // Try to get currently active variant and field
2315                        if let Tracker::Enum {
2316                            variant,
2317                            current_child,
2318                            ..
2319                        } = &frame.tracker
2320                        {
2321                            if i == 0 {
2322                                // Use Display for the root enum shape
2323                                path_components.push(format!("{}", frame.shape));
2324                            }
2325                            path_components.push(format!("::{}", variant.name));
2326                            if let Some(idx) = *current_child {
2327                                if let Some(field) = variant.data.fields.get(idx) {
2328                                    path_components.push(format!(".{}", field.name));
2329                                }
2330                            }
2331                        } else if i == 0 {
2332                            // just the enum display
2333                            path_components.push(format!("{}", frame.shape));
2334                        }
2335                    }
2336                    UserType::Union(_union_type) => {
2337                        path_components.push(format!("{}", frame.shape));
2338                    }
2339                    UserType::Opaque => {
2340                        path_components.push("<opaque>".to_string());
2341                    }
2342                },
2343                Type::Sequence(seq_type) => match seq_type {
2344                    facet_core::SequenceType::Array(_array_def) => {
2345                        // Try to show current element index
2346                        if let Tracker::Array {
2347                            current_child: Some(idx),
2348                            ..
2349                        } = &frame.tracker
2350                        {
2351                            path_components.push(format!("[{idx}]"));
2352                        }
2353                    }
2354                    // You can add more for Slice, Vec, etc., if applicable
2355                    _ => {
2356                        // just indicate "[]" for sequence
2357                        path_components.push("[]".to_string());
2358                    }
2359                },
2360                Type::Pointer(_) => {
2361                    // Indicate deref
2362                    path_components.push("*".to_string());
2363                }
2364                _ => {
2365                    // No structural path
2366                }
2367            }
2368        }
2369        // Merge the path_components into a single string
2370        for component in path_components {
2371            out.push_str(&component);
2372        }
2373        out
2374    }
2375
2376    /// Returns the shape of the current frame.
2377    #[inline]
2378    pub fn shape(&self) -> &'shape Shape<'shape> {
2379        self.frames
2380            .last()
2381            .expect("Partial always has at least one frame")
2382            .shape
2383    }
2384
2385    /// Returns the innermost shape (alias for shape(), for compatibility)
2386    #[inline]
2387    pub fn innermost_shape(&self) -> &'shape Shape<'shape> {
2388        self.shape()
2389    }
2390
2391    /// Check if a struct field at the given index has been set
2392    pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError<'shape>> {
2393        let frame = self.frames.last().ok_or(ReflectError::NoActiveFrame)?;
2394
2395        match &frame.tracker {
2396            Tracker::Uninit => Ok(false),
2397            Tracker::Init => Ok(true),
2398            Tracker::Struct { iset, .. } => Ok(iset.get(index)),
2399            Tracker::Enum { data, .. } => {
2400                // Check if the field is already marked as set
2401                if data.get(index) {
2402                    return Ok(true);
2403                }
2404
2405                // For enum variant fields that are empty structs, they are always initialized
2406                if let Tracker::Enum { variant, .. } = &frame.tracker {
2407                    if let Some(field) = variant.data.fields.get(index) {
2408                        if let Type::User(UserType::Struct(field_struct)) = field.shape.ty {
2409                            if field_struct.fields.is_empty() {
2410                                return Ok(true);
2411                            }
2412                        }
2413                    }
2414                }
2415
2416                Ok(false)
2417            }
2418            Tracker::Option { building_inner } => {
2419                // For Options, index 0 represents the inner value
2420                if index == 0 {
2421                    Ok(!building_inner)
2422                } else {
2423                    Err(ReflectError::InvalidOperation {
2424                        operation: "is_field_set",
2425                        reason: "Option only has one field (index 0)",
2426                    })
2427                }
2428            }
2429            _ => Err(ReflectError::InvalidOperation {
2430                operation: "is_field_set",
2431                reason: "Current frame is not a struct, enum variant, or option",
2432            }),
2433        }
2434    }
2435
2436    /// Find the index of a field by name in the current struct
2437    pub fn field_index(&self, field_name: &str) -> Option<usize> {
2438        let frame = self.frames.last()?;
2439
2440        match frame.shape.ty {
2441            Type::User(UserType::Struct(struct_def)) => {
2442                struct_def.fields.iter().position(|f| f.name == field_name)
2443            }
2444            Type::User(UserType::Enum(_)) => {
2445                // If we're in an enum variant, check its fields
2446                if let Tracker::Enum { variant, .. } = &frame.tracker {
2447                    variant
2448                        .data
2449                        .fields
2450                        .iter()
2451                        .position(|f| f.name == field_name)
2452                } else {
2453                    None
2454                }
2455            }
2456            _ => None,
2457        }
2458    }
2459
2460    /// Get the currently selected variant for an enum
2461    pub fn selected_variant(&self) -> Option<Variant<'shape>> {
2462        let frame = self.frames.last()?;
2463
2464        match &frame.tracker {
2465            Tracker::Enum { variant, .. } => Some(**variant),
2466            _ => None,
2467        }
2468    }
2469
2470    /// Find a variant by name in the current enum
2471    pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'shape Variant<'shape>)> {
2472        let frame = self.frames.last()?;
2473
2474        if let Type::User(UserType::Enum(enum_def)) = frame.shape.ty {
2475            enum_def
2476                .variants
2477                .iter()
2478                .enumerate()
2479                .find(|(_, v)| v.name == variant_name)
2480        } else {
2481            None
2482        }
2483    }
2484
2485    /// Begin building the Some variant of an Option
2486    pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2487        self.require_active()?;
2488        let frame = self.frames.last_mut().unwrap();
2489
2490        // Verify we're working with an Option
2491        let option_def = match frame.shape.def {
2492            Def::Option(def) => def,
2493            _ => {
2494                return Err(ReflectError::WasNotA {
2495                    expected: "Option",
2496                    actual: frame.shape,
2497                });
2498            }
2499        };
2500
2501        // Initialize the tracker for Option building
2502        if matches!(frame.tracker, Tracker::Uninit) {
2503            frame.tracker = Tracker::Option {
2504                building_inner: true,
2505            };
2506        }
2507
2508        // Get the inner type shape
2509        let inner_shape = option_def.t;
2510
2511        // Allocate memory for the inner value
2512        let inner_layout =
2513            inner_shape
2514                .layout
2515                .sized_layout()
2516                .map_err(|_| ReflectError::Unsized {
2517                    shape: inner_shape,
2518                    operation: "begin_some, allocating Option inner value",
2519                })?;
2520
2521        let inner_data = if inner_layout.size() == 0 {
2522            // For ZST, use a non-null but unallocated pointer
2523            PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2524        } else {
2525            // Allocate memory for the inner value
2526            let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2527            if ptr.is_null() {
2528                alloc::alloc::handle_alloc_error(inner_layout);
2529            }
2530            PtrUninit::new(ptr)
2531        };
2532
2533        // Create a new frame for the inner value
2534        let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
2535        self.frames.push(inner_frame);
2536
2537        Ok(self)
2538    }
2539
2540    /// Begin building the inner value of a wrapper type
2541    pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2542        self.require_active()?;
2543
2544        // Get the inner shape and check for try_from
2545        let (inner_shape, has_try_from, parent_shape) = {
2546            let frame = self.frames.last().unwrap();
2547            if let Some(inner_fn) = frame.shape.inner {
2548                let inner_shape = inner_fn();
2549                let has_try_from = frame
2550                    .shape
2551                    .vtable
2552                    .sized()
2553                    .and_then(|v| (v.try_from)())
2554                    .is_some();
2555                (Some(inner_shape), has_try_from, frame.shape)
2556            } else {
2557                (None, false, frame.shape)
2558            }
2559        };
2560
2561        if let Some(inner_shape) = inner_shape {
2562            if has_try_from {
2563                // Create a conversion frame with the inner shape
2564
2565                // For conversion frames, we leave the parent tracker unchanged
2566                // This allows automatic conversion detection to work properly
2567
2568                // Allocate memory for the inner value (conversion source)
2569                let inner_layout =
2570                    inner_shape
2571                        .layout
2572                        .sized_layout()
2573                        .map_err(|_| ReflectError::Unsized {
2574                            shape: inner_shape,
2575                            operation: "begin_inner, getting inner layout",
2576                        })?;
2577
2578                let inner_data = if inner_layout.size() == 0 {
2579                    // For ZST, use a non-null but unallocated pointer
2580                    PtrUninit::new(core::ptr::NonNull::<u8>::dangling().as_ptr())
2581                } else {
2582                    // Allocate memory for the inner value
2583                    let ptr = unsafe { alloc::alloc::alloc(inner_layout) };
2584                    if ptr.is_null() {
2585                        alloc::alloc::handle_alloc_error(inner_layout);
2586                    }
2587                    PtrUninit::new(ptr)
2588                };
2589
2590                // For conversion frames, we create a frame directly with the inner shape
2591                // This allows setting values of the inner type which will be converted
2592                // The automatic conversion detection in end() will handle the conversion
2593                trace!(
2594                    "begin_inner: Creating frame for inner type {inner_shape} (parent is {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!("begin_inner: No try_from for {parent_shape}, using field navigation");
2604                self.begin_nth_field(0)
2605            }
2606        } else {
2607            Err(ReflectError::OperationFailed {
2608                shape: parent_shape,
2609                operation: "type does not have an inner value",
2610            })
2611        }
2612    }
2613
2614    /// Copy a value from a Peek into the current position (safe alternative to set_shape)
2615    pub fn set_from_peek(
2616        &mut self,
2617        peek: &Peek<'_, '_, 'shape>,
2618    ) -> Result<&mut Self, ReflectError<'shape>> {
2619        self.require_active()?;
2620
2621        // Get the source value's pointer and shape
2622        let src_ptr = peek.data();
2623        let src_shape = peek.shape();
2624
2625        // Safety: This is a safe wrapper around set_shape
2626        // The peek guarantees the source data is valid for its shape
2627        unsafe { self.set_shape(src_ptr.thin().unwrap(), src_shape) }
2628    }
2629
2630    /// Copy a field from a struct's default value (safe wrapper for deserialization)
2631    /// This method creates the Peek internally to avoid exposing unsafe code to callers
2632    pub fn set_field_from_default(
2633        &mut self,
2634        field_data: PtrConst<'_>,
2635        field_shape: &'shape Shape<'shape>,
2636    ) -> Result<&mut Self, ReflectError<'shape>> {
2637        self.require_active()?;
2638
2639        // Safety: The caller guarantees that field_data points to valid data for field_shape
2640        // This is typically used when copying default values during deserialization
2641        unsafe { self.set_shape(field_data, field_shape) }
2642    }
2643
2644    /// Fill all unset fields from the struct's default value
2645    /// This is a safe API for format deserializers that forbid unsafe code
2646    pub fn fill_unset_fields_from_default(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2647        self.require_active()?;
2648
2649        let frame = self.frames.last().unwrap();
2650        let shape = frame.shape;
2651
2652        // Check if this is a struct with the default attribute
2653        if !shape.has_default_attr() {
2654            return Ok(self);
2655        }
2656
2657        // Make sure we're working with a struct
2658        let struct_def = match shape.ty {
2659            Type::User(UserType::Struct(sd)) => sd,
2660            _ => return Ok(self), // Not a struct, nothing to do
2661        };
2662
2663        // Check if any fields are unset
2664        let mut has_unset = false;
2665        for index in 0..struct_def.fields.len() {
2666            if !self.is_field_set(index)? {
2667                has_unset = true;
2668                break;
2669            }
2670        }
2671
2672        if !has_unset {
2673            return Ok(self); // All fields are set, nothing to do
2674        }
2675
2676        // Create a default instance
2677        let default_val = Partial::alloc_shape(shape)?.set_default()?.build()?;
2678        let peek = default_val.peek();
2679
2680        // Convert to struct peek
2681        let struct_peek = peek
2682            .into_struct()
2683            .map_err(|_| ReflectError::OperationFailed {
2684                shape,
2685                operation: "expected struct peek for default value",
2686            })?;
2687
2688        // Copy unset fields from the default
2689        for (index, _field) in struct_def.fields.iter().enumerate() {
2690            if !self.is_field_set(index)? {
2691                self.begin_nth_field(index)?;
2692
2693                // Get the field from the default value
2694                let def_field =
2695                    struct_peek
2696                        .field(index)
2697                        .map_err(|_| ReflectError::OperationFailed {
2698                            shape,
2699                            operation: "failed to get field from default struct",
2700                        })?;
2701
2702                self.set_from_peek(&def_field)?;
2703                self.end()?;
2704            }
2705        }
2706
2707        Ok(self)
2708    }
2709
2710    /// Convenience shortcut: sets the nth element of an array directly to value, popping after.
2711    pub fn set_nth_element<U>(
2712        &mut self,
2713        idx: usize,
2714        value: U,
2715    ) -> Result<&mut Self, ReflectError<'shape>>
2716    where
2717        U: Facet<'facet>,
2718    {
2719        self.begin_nth_element(idx)?.set(value)?.end()
2720    }
2721
2722    /// Convenience shortcut: sets the field at index `idx` directly to value, popping after.
2723    pub fn set_nth_field<U>(
2724        &mut self,
2725        idx: usize,
2726        value: U,
2727    ) -> Result<&mut Self, ReflectError<'shape>>
2728    where
2729        U: Facet<'facet>,
2730    {
2731        self.begin_nth_field(idx)?.set(value)?.end()
2732    }
2733
2734    /// Convenience shortcut: sets the named field to value, popping after.
2735    pub fn set_field<U>(
2736        &mut self,
2737        field_name: &str,
2738        value: U,
2739    ) -> Result<&mut Self, ReflectError<'shape>>
2740    where
2741        U: Facet<'facet>,
2742    {
2743        self.begin_field(field_name)?.set(value)?.end()
2744    }
2745
2746    /// Convenience shortcut: sets the nth field of an enum variant directly to value, popping after.
2747    pub fn set_nth_enum_field<U>(
2748        &mut self,
2749        idx: usize,
2750        value: U,
2751    ) -> Result<&mut Self, ReflectError<'shape>>
2752    where
2753        U: Facet<'facet>,
2754    {
2755        self.begin_nth_enum_field(idx)?.set(value)?.end()
2756    }
2757
2758    /// Convenience shortcut: sets the key for a map key-value insertion, then pops after.
2759    pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2760    where
2761        U: Facet<'facet>,
2762    {
2763        self.begin_key()?.set(value)?.end()
2764    }
2765
2766    /// Convenience shortcut: sets the value for a map key-value insertion, then pops after.
2767    pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2768    where
2769        U: Facet<'facet>,
2770    {
2771        self.begin_value()?.set(value)?.end()
2772    }
2773
2774    /// Shorthand for: begin_list_item(), set, end
2775    pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2776    where
2777        U: Facet<'facet>,
2778    {
2779        self.begin_list_item()?.set(value)?.end()
2780    }
2781}
2782
2783/// A typed wrapper around `Partial`, for when you want to statically
2784/// ensure that `build` gives you the proper type.
2785pub struct TypedPartial<'facet, 'shape, T> {
2786    inner: Partial<'facet, 'shape>,
2787    phantom: PhantomData<T>,
2788}
2789
2790impl<'facet, 'shape, T> TypedPartial<'facet, 'shape, T> {
2791    /// Unwraps the underlying Partial, consuming self.
2792    pub fn inner_mut(&mut self) -> &mut Partial<'facet, 'shape> {
2793        &mut self.inner
2794    }
2795
2796    /// Builds the value and returns a `Box<T>`
2797    pub fn build(&mut self) -> Result<Box<T>, ReflectError<'shape>>
2798    where
2799        T: Facet<'facet>,
2800        'facet: 'shape,
2801    {
2802        trace!(
2803            "TypedPartial::build: Building value for type {} which should == {}",
2804            T::SHAPE,
2805            self.inner.shape()
2806        );
2807        let heap_value = self.inner.build()?;
2808        trace!(
2809            "TypedPartial::build: Built heap value with shape: {}",
2810            heap_value.shape()
2811        );
2812        // Safety: HeapValue was constructed from T and the shape layout is correct.
2813        let result = unsafe { heap_value.into_box_unchecked::<T>() };
2814        trace!("TypedPartial::build: Successfully converted to Box<T>");
2815        Ok(result)
2816    }
2817
2818    /// Sets a value wholesale into the current frame
2819    pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
2820    where
2821        U: Facet<'facet>,
2822    {
2823        self.inner.set(value)?;
2824        Ok(self)
2825    }
2826
2827    /// Sets a value into the current frame by shape, for shape-based operations
2828    pub fn set_shape(
2829        &mut self,
2830        src_value: PtrConst<'_>,
2831        src_shape: &'shape Shape<'shape>,
2832    ) -> Result<&mut Self, ReflectError<'shape>> {
2833        unsafe { self.inner.set_shape(src_value, src_shape)? };
2834        Ok(self)
2835    }
2836
2837    /// Forwards begin_field to the inner partial instance.
2838    pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError<'shape>> {
2839        self.inner.begin_field(field_name)?;
2840        Ok(self)
2841    }
2842
2843    /// Forwards begin_nth_field to the inner partial instance.
2844    pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
2845        self.inner.begin_nth_field(idx)?;
2846        Ok(self)
2847    }
2848
2849    /// Forwards begin_nth_element to the inner partial instance.
2850    pub fn begin_nth_element(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
2851        self.inner.begin_nth_element(idx)?;
2852        Ok(self)
2853    }
2854
2855    /// Forwards begin_smart_ptr to the inner partial instance.
2856    pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2857        self.inner.begin_smart_ptr()?;
2858        Ok(self)
2859    }
2860
2861    /// Forwards end to the inner partial instance.
2862    pub fn end(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2863        self.inner.end()?;
2864        Ok(self)
2865    }
2866
2867    /// Forwards set_default to the inner partial instance.
2868    pub fn set_default(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2869        self.inner.set_default()?;
2870        Ok(self)
2871    }
2872
2873    /// Forwards set_from_function to the inner partial instance.
2874    pub fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError<'shape>>
2875    where
2876        F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError<'shape>>,
2877    {
2878        self.inner.set_from_function(f)?;
2879        Ok(self)
2880    }
2881
2882    /// Forwards parse_from_str to the inner partial instance.
2883    pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError<'shape>> {
2884        self.inner.parse_from_str(s)?;
2885        Ok(self)
2886    }
2887
2888    /// Forwards begin_variant to the inner partial instance.
2889    pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError<'shape>> {
2890        self.inner.select_variant(discriminant)?;
2891        Ok(self)
2892    }
2893
2894    /// Forwards begin_variant_named to the inner partial instance.
2895    pub fn select_variant_named(
2896        &mut self,
2897        variant_name: &str,
2898    ) -> Result<&mut Self, ReflectError<'shape>> {
2899        self.inner.select_variant_named(variant_name)?;
2900        Ok(self)
2901    }
2902
2903    /// Forwards select_nth_variant to the inner partial instance.
2904    pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError<'shape>> {
2905        self.inner.select_nth_variant(index)?;
2906        Ok(self)
2907    }
2908
2909    /// Forwards begin_nth_enum_field to the inner partial instance.
2910    pub fn begin_nth_enum_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError<'shape>> {
2911        self.inner.begin_nth_enum_field(idx)?;
2912        Ok(self)
2913    }
2914
2915    /// Forwards begin_list to the inner partial instance.
2916    pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2917        self.inner.begin_list()?;
2918        Ok(self)
2919    }
2920
2921    /// Forwards begin_list_item to the inner partial instance.
2922    pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2923        self.inner.begin_list_item()?;
2924        Ok(self)
2925    }
2926
2927    /// Forwards begin_map to the inner partial instance.
2928    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2929        self.inner.begin_map()?;
2930        Ok(self)
2931    }
2932
2933    /// Forwards begin_key to the inner partial instance.
2934    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2935        self.inner.begin_key()?;
2936        Ok(self)
2937    }
2938
2939    /// Forwards begin_value to the inner partial instance.
2940    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
2941        self.inner.begin_value()?;
2942        Ok(self)
2943    }
2944
2945    /// Returns a human-readable path representing the current traversal in the builder,
2946    /// e.g., `RootStruct.fieldName[index].subfield`.
2947    pub fn path(&self) -> String {
2948        self.inner.path()
2949    }
2950
2951    /// Returns the shape of the current frame.
2952    pub fn shape(&self) -> &'shape Shape<'shape> {
2953        self.inner.shape()
2954    }
2955
2956    /// Convenience shortcut: sets the nth element of an array directly to value, popping after.
2957    pub fn set_nth_element<U>(
2958        &mut self,
2959        idx: usize,
2960        value: U,
2961    ) -> Result<&mut Self, ReflectError<'shape>>
2962    where
2963        U: Facet<'facet>,
2964    {
2965        self.inner.set_nth_element(idx, value)?;
2966        Ok(self)
2967    }
2968
2969    /// Convenience shortcut: sets the field at index `idx` directly to value, popping after.
2970    pub fn set_nth_field<U>(
2971        &mut self,
2972        idx: usize,
2973        value: U,
2974    ) -> Result<&mut Self, ReflectError<'shape>>
2975    where
2976        U: Facet<'facet>,
2977    {
2978        self.inner.set_nth_field(idx, value)?;
2979        Ok(self)
2980    }
2981
2982    /// Convenience shortcut: sets the named field to value, popping after.
2983    pub fn set_field<U>(
2984        &mut self,
2985        field_name: &str,
2986        value: U,
2987    ) -> Result<&mut Self, ReflectError<'shape>>
2988    where
2989        U: Facet<'facet>,
2990    {
2991        self.inner.set_field(field_name, value)?;
2992        Ok(self)
2993    }
2994
2995    /// Convenience shortcut: sets the nth field of an enum variant directly to value, popping after.
2996    pub fn set_nth_enum_field<U>(
2997        &mut self,
2998        idx: usize,
2999        value: U,
3000    ) -> Result<&mut Self, ReflectError<'shape>>
3001    where
3002        U: Facet<'facet>,
3003    {
3004        self.inner.set_nth_enum_field(idx, value)?;
3005        Ok(self)
3006    }
3007
3008    /// Convenience shortcut: sets the key for a map key-value insertion, then pops after.
3009    pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
3010    where
3011        U: Facet<'facet>,
3012    {
3013        self.inner.set_key(value)?;
3014        Ok(self)
3015    }
3016
3017    /// Convenience shortcut: sets the value for a map key-value insertion, then pops after.
3018    pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
3019    where
3020        U: Facet<'facet>,
3021    {
3022        self.inner.set_value(value)?;
3023        Ok(self)
3024    }
3025
3026    /// Shorthand for: begin_list_item(), set, end
3027    pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError<'shape>>
3028    where
3029        U: Facet<'facet>,
3030    {
3031        self.inner.push(value)?;
3032        Ok(self)
3033    }
3034
3035    /// Begin building the Some variant of an Option
3036    pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
3037        self.inner.begin_some()?;
3038        Ok(self)
3039    }
3040
3041    /// Begin building the inner value of a wrapper type
3042    pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError<'shape>> {
3043        self.inner.begin_inner()?;
3044        Ok(self)
3045    }
3046}
3047
3048impl<'facet, 'shape, T> core::fmt::Debug for TypedPartial<'facet, 'shape, T> {
3049    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3050        f.debug_struct("TypedPartial")
3051            .field("shape", &self.inner.frames.last().map(|frame| frame.shape))
3052            .finish()
3053    }
3054}
3055
3056impl<'facet, 'shape> Drop for Partial<'facet, 'shape> {
3057    fn drop(&mut self) {
3058        trace!("🧹 Partial is being dropped");
3059
3060        // We need to properly drop all initialized fields
3061        while let Some(frame) = self.frames.pop() {
3062            match &frame.tracker {
3063                Tracker::Uninit => {
3064                    // Nothing was initialized, nothing to drop
3065                }
3066                Tracker::Init => {
3067                    // Fully initialized, drop it
3068                    if let Some(drop_fn) =
3069                        frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3070                    {
3071                        unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3072                    }
3073                }
3074                Tracker::Array { iset, .. } => {
3075                    // Drop initialized array elements
3076                    if let Type::Sequence(facet_core::SequenceType::Array(array_def)) =
3077                        frame.shape.ty
3078                    {
3079                        let element_layout = array_def.t.layout.sized_layout().ok();
3080                        if let Some(layout) = element_layout {
3081                            for idx in 0..array_def.n {
3082                                if iset.get(idx) {
3083                                    let offset = layout.size() * idx;
3084                                    let element_ptr = unsafe { frame.data.field_init_at(offset) };
3085                                    if let Some(drop_fn) =
3086                                        array_def.t.vtable.sized().and_then(|v| (v.drop_in_place)())
3087                                    {
3088                                        unsafe { drop_fn(element_ptr) };
3089                                    }
3090                                }
3091                            }
3092                        }
3093                    }
3094                }
3095                Tracker::Struct { iset, .. } => {
3096                    // Drop initialized struct fields
3097                    if let Type::User(UserType::Struct(struct_type)) = frame.shape.ty {
3098                        for (idx, field) in struct_type.fields.iter().enumerate() {
3099                            if iset.get(idx) {
3100                                // This field was initialized, drop it
3101                                let field_ptr = unsafe { frame.data.field_init_at(field.offset) };
3102                                if let Some(drop_fn) =
3103                                    field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3104                                {
3105                                    unsafe { drop_fn(field_ptr) };
3106                                }
3107                            }
3108                        }
3109                    }
3110                }
3111                Tracker::Enum { variant, data, .. } => {
3112                    // Drop initialized enum variant fields
3113                    for (idx, field) in variant.data.fields.iter().enumerate() {
3114                        if data.get(idx) {
3115                            // This field was initialized, drop it
3116                            let field_ptr =
3117                                unsafe { frame.data.as_mut_byte_ptr().add(field.offset) };
3118                            if let Some(drop_fn) =
3119                                field.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3120                            {
3121                                unsafe { drop_fn(PtrMut::new(field_ptr)) };
3122                            }
3123                        }
3124                    }
3125                }
3126                Tracker::SmartPointer { is_initialized } => {
3127                    // Drop the initialized Box
3128                    if *is_initialized {
3129                        if let Some(drop_fn) =
3130                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3131                        {
3132                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3133                        }
3134                    }
3135                    // Note: we don't deallocate the inner value here because
3136                    // the Box's drop will handle that
3137                }
3138                Tracker::SmartPointerStr { .. } => {
3139                    // nothing to do for now
3140                }
3141                Tracker::SmartPointerSlice { vtable, .. } => {
3142                    // Free the slice builder
3143                    let builder_ptr = unsafe { frame.data.assume_init() };
3144                    unsafe {
3145                        (vtable.free_fn)(builder_ptr);
3146                    }
3147                }
3148                Tracker::List { is_initialized, .. } => {
3149                    // Drop the initialized List
3150                    if *is_initialized {
3151                        if let Some(drop_fn) =
3152                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3153                        {
3154                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3155                        }
3156                    }
3157                }
3158                Tracker::Map {
3159                    is_initialized,
3160                    insert_state,
3161                } => {
3162                    // Drop the initialized Map
3163                    if *is_initialized {
3164                        if let Some(drop_fn) =
3165                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3166                        {
3167                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3168                        }
3169                    }
3170
3171                    // Clean up any in-progress insertion state
3172                    match insert_state {
3173                        MapInsertState::PushingKey { key_ptr } => {
3174                            if let Some(key_ptr) = key_ptr {
3175                                // Deallocate the key buffer
3176                                if let Def::Map(map_def) = frame.shape.def {
3177                                    if let Ok(key_shape) = map_def.k().layout.sized_layout() {
3178                                        if key_shape.size() > 0 {
3179                                            unsafe {
3180                                                alloc::alloc::dealloc(
3181                                                    key_ptr.as_mut_byte_ptr(),
3182                                                    key_shape,
3183                                                )
3184                                            };
3185                                        }
3186                                    }
3187                                }
3188                            }
3189                        }
3190                        MapInsertState::PushingValue { key_ptr, value_ptr } => {
3191                            // Drop and deallocate both key and value buffers
3192                            if let Def::Map(map_def) = frame.shape.def {
3193                                // Drop and deallocate the key
3194                                if let Some(drop_fn) =
3195                                    map_def.k().vtable.sized().and_then(|v| (v.drop_in_place)())
3196                                {
3197                                    unsafe { drop_fn(PtrMut::new(key_ptr.as_mut_byte_ptr())) };
3198                                }
3199                                if let Ok(key_shape) = map_def.k().layout.sized_layout() {
3200                                    if key_shape.size() > 0 {
3201                                        unsafe {
3202                                            alloc::alloc::dealloc(
3203                                                key_ptr.as_mut_byte_ptr(),
3204                                                key_shape,
3205                                            )
3206                                        };
3207                                    }
3208                                }
3209
3210                                // Drop and deallocate the value if it exists
3211                                if let Some(value_ptr) = value_ptr {
3212                                    if let Ok(value_shape) = map_def.v().layout.sized_layout() {
3213                                        if value_shape.size() > 0 {
3214                                            unsafe {
3215                                                alloc::alloc::dealloc(
3216                                                    value_ptr.as_mut_byte_ptr(),
3217                                                    value_shape,
3218                                                )
3219                                            };
3220                                        }
3221                                    }
3222                                }
3223                            }
3224                        }
3225                        MapInsertState::Idle => {}
3226                    }
3227                }
3228                Tracker::Option { building_inner } => {
3229                    // If we're building the inner value, it will be handled by the Option vtable
3230                    // No special cleanup needed here as the Option will either be properly
3231                    // initialized or remain uninitialized
3232                    if !building_inner {
3233                        // Option is fully initialized, drop it normally
3234                        if let Some(drop_fn) =
3235                            frame.shape.vtable.sized().and_then(|v| (v.drop_in_place)())
3236                        {
3237                            unsafe { drop_fn(PtrMut::new(frame.data.as_mut_byte_ptr())) };
3238                        }
3239                    }
3240                }
3241            }
3242
3243            // Only deallocate if this frame owns the allocation
3244            if let FrameOwnership::Owned = frame.ownership {
3245                if let Ok(layout) = frame.shape.layout.sized_layout() {
3246                    if layout.size() > 0 {
3247                        unsafe { alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout) };
3248                    }
3249                }
3250            }
3251        }
3252    }
3253}