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