facet_reflect/partial/
mod.rs

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