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