facet_deserialize/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(missing_docs)]
3#![warn(clippy::std_instead_of_core)]
4#![warn(clippy::std_instead_of_alloc)]
5#![forbid(unsafe_code)]
6#![doc = include_str!("../README.md")]
7
8extern crate alloc;
9
10use alloc::string::ToString;
11use alloc::{vec, vec::Vec};
12use core::fmt::Debug;
13use facet_core::{NumericType, PrimitiveType};
14
15mod error;
16use alloc::borrow::Cow;
17
18pub use error::*;
19
20mod span;
21use facet_core::{Characteristic, Def, Facet, FieldFlags, PointerType, StructKind, Type, UserType};
22use owo_colors::OwoColorize;
23pub use span::*;
24
25use facet_reflect::{HeapValue, Partial, ReflectError};
26use log::trace;
27
28#[derive(PartialEq, Debug, Clone)]
29/// A scalar value used during deserialization.
30/// `u64` and `i64` are separated because `i64` doesn't fit in `u64`,
31/// but having `u64` is a fast path for 64-bit architectures — no need to
32/// go through `u128` / `i128` for everything
33pub enum Scalar<'input> {
34    /// Owned or borrowed string data.
35    String(Cow<'input, str>),
36    /// Unsigned 64-bit integer scalar.
37    U64(u64),
38    /// Signed 64-bit integer scalar.
39    I64(i64),
40    /// 64-bit floating-point scalar.
41    F64(f64),
42    /// 128-bit unsigned integer scalar.
43    U128(u128),
44    /// 128-bit signed integer scalar.
45    I128(i128),
46    /// Boolean scalar.
47    Bool(bool),
48    /// Null scalar (e.g. for formats supporting explicit null).
49    Null,
50}
51
52#[derive(PartialEq, Debug, Clone)]
53/// Expected next input token or structure during deserialization.
54pub enum Expectation {
55    /// Accept a value.
56    Value,
57    /// Expect an object key or the end of an object.
58    ObjectKeyOrObjectClose,
59    /// Expect a value inside an object.
60    ObjectVal,
61    /// Expect a list item or the end of a list.
62    ListItemOrListClose,
63}
64
65#[derive(PartialEq, Debug, Clone)]
66/// Outcome of parsing the next input element.
67pub enum Outcome<'input> {
68    /// Parsed a scalar value.
69    Scalar(Scalar<'input>),
70    /// Starting a list/array.
71    ListStarted,
72    /// Ending a list/array.
73    ListEnded,
74    /// Starting an object/map.
75    ObjectStarted,
76    /// Ending an object/map.
77    ObjectEnded,
78}
79
80impl<'input> From<Scalar<'input>> for Outcome<'input> {
81    fn from(scalar: Scalar<'input>) -> Self {
82        Outcome::Scalar(scalar)
83    }
84}
85
86use core::fmt;
87
88/// Display implementation for `Outcome`, focusing on user-friendly descriptions.
89impl fmt::Display for Outcome<'_> {
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        match self {
92            Outcome::Scalar(scalar) => write!(f, "scalar {scalar}"),
93            Outcome::ListStarted => write!(f, "list start"),
94            Outcome::ListEnded => write!(f, "list end"),
95            Outcome::ObjectStarted => write!(f, "object start"),
96            Outcome::ObjectEnded => write!(f, "object end"),
97        }
98    }
99}
100
101/// Display implementation for `Scalar`, for use in displaying `Outcome`.
102impl fmt::Display for Scalar<'_> {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        match self {
105            Scalar::String(s) => write!(f, "string \"{s}\""),
106            Scalar::U64(val) => write!(f, "u64 {val}"),
107            Scalar::I64(val) => write!(f, "i64 {val}"),
108            Scalar::F64(val) => write!(f, "f64 {val}"),
109            Scalar::U128(val) => write!(f, "u128 {val}"),
110            Scalar::I128(val) => write!(f, "i128 {val}"),
111            Scalar::Bool(val) => write!(f, "bool {val}"),
112            Scalar::Null => write!(f, "null"),
113        }
114    }
115}
116
117impl Outcome<'_> {
118    fn into_owned(self) -> Outcome<'static> {
119        match self {
120            Outcome::Scalar(scalar) => {
121                let owned_scalar = match scalar {
122                    Scalar::String(cow) => Scalar::String(Cow::Owned(cow.into_owned())),
123                    Scalar::U64(val) => Scalar::U64(val),
124                    Scalar::I64(val) => Scalar::I64(val),
125                    Scalar::F64(val) => Scalar::F64(val),
126                    Scalar::U128(val) => Scalar::U128(val),
127                    Scalar::I128(val) => Scalar::I128(val),
128                    Scalar::Bool(val) => Scalar::Bool(val),
129                    Scalar::Null => Scalar::Null,
130                };
131                Outcome::Scalar(owned_scalar)
132            }
133            Outcome::ListStarted => Outcome::ListStarted,
134            Outcome::ListEnded => Outcome::ListEnded,
135            Outcome::ObjectStarted => Outcome::ObjectStarted,
136            Outcome::ObjectEnded => Outcome::ObjectEnded,
137        }
138    }
139}
140
141/// Carries the current parsing state and the in-progress value during deserialization.
142/// This bundles the mutable context that must be threaded through parsing steps.
143pub struct NextData<'input, 'facet, 'shape>
144where
145    'input: 'facet,
146{
147    /// The offset we're supposed to start parsing from
148    start: usize,
149
150    /// Controls the parsing flow and stack state.
151    runner: StackRunner<'input>,
152
153    /// Holds the intermediate representation of the value being built.
154    pub wip: Partial<'facet, 'shape>,
155}
156
157impl<'input, 'facet, 'shape> NextData<'input, 'facet, 'shape>
158where
159    'input: 'facet,
160{
161    /// Returns the input (from the start! not from the current position)
162    pub fn input(&self) -> &'input [u8] {
163        self.runner.input
164    }
165
166    /// Returns the parsing start offset.
167    pub fn start(&self) -> usize {
168        self.start
169    }
170}
171
172/// The result of advancing the parser: updated state and parse outcome or error.
173pub type NextResult<'input, 'facet, 'shape, T, E> =
174    (NextData<'input, 'facet, 'shape>, Result<T, E>);
175
176/// Trait defining a deserialization format.
177/// Provides the next parsing step based on current state and expected input.
178pub trait Format {
179    /// The lowercase source ID of the format, used for error reporting.
180    fn source(&self) -> &'static str;
181
182    /// Advance the parser with current state and expectation, producing the next outcome or error.
183    #[allow(clippy::type_complexity)]
184    fn next<'input, 'facet, 'shape>(
185        &mut self,
186        nd: NextData<'input, 'facet, 'shape>,
187        expectation: Expectation,
188    ) -> NextResult<'input, 'facet, 'shape, Spanned<Outcome<'input>>, Spanned<DeserErrorKind<'shape>>>
189    where
190        'shape: 'input;
191
192    /// Skip the next value; used to ignore an input.
193    #[allow(clippy::type_complexity)]
194    fn skip<'input, 'facet, 'shape>(
195        &mut self,
196        nd: NextData<'input, 'facet, 'shape>,
197    ) -> NextResult<'input, 'facet, 'shape, Span, Spanned<DeserErrorKind<'shape>>>
198    where
199        'shape: 'input;
200}
201
202/// Instructions guiding the parsing flow, indicating the next expected action or token.
203#[derive(Debug, Clone, Copy, PartialEq, Eq)]
204pub enum Instruction {
205    /// Expect a value, specifying the context or reason.
206    Value(ValueReason),
207    /// Skip the next value; used to ignore an input.
208    SkipValue,
209    /// Indicate completion of a structure or value; triggers popping from stack.
210    Pop(PopReason),
211    /// Expect an object key or the end of an object.
212    ObjectKeyOrObjectClose,
213    /// Expect a list item or the end of a list.
214    ListItemOrListClose,
215}
216
217/// Reasons for expecting a value, reflecting the current parse context.
218#[derive(Debug, Clone, Copy, PartialEq, Eq)]
219pub enum ValueReason {
220    /// Parsing at the root level.
221    TopLevel,
222    /// Parsing a value inside an object.
223    ObjectVal,
224}
225
226/// Reasons for popping a state from the stack, indicating why a scope is ended.
227#[derive(Debug, Clone, Copy, PartialEq, Eq)]
228pub enum PopReason {
229    /// Ending the top-level parsing scope.
230    TopLevel,
231    /// Ending a value within an object.
232    ObjectVal,
233    /// Ending value within a list
234    ListVal,
235    /// Ending a `Some()` in an option
236    Some,
237    /// Ending a smart pointer (ie. wrapping a `T` back into a `Box<T>`, or `Arc<T>` etc.)
238    SmartPointer,
239    /// Ending a wrapper value such as a newtype
240    Wrapper,
241}
242
243mod deser_impl {
244    use super::*;
245
246    /// Deserialize a value of type `T` from raw input bytes using format `F`.
247    ///
248    /// This function sets up the initial working state and drives the deserialization process,
249    /// ensuring that the resulting value is fully materialized and valid.
250    pub fn deserialize<'input, 'facet, 'shape, T, F>(
251        input: &'input [u8],
252        format: &mut F,
253    ) -> Result<T, DeserError<'input, 'shape>>
254    where
255        T: Facet<'facet>,
256        F: Format + 'shape,
257        'input: 'facet,
258        'shape: 'input,
259    {
260        // Run the entire deserialization process and capture any errors
261        let result: Result<T, DeserError<'input, 'shape>> = {
262            let source = format.source();
263
264            // Step 1: Allocate shape
265            let wip = match Partial::alloc_shape(T::SHAPE) {
266                Ok(wip) => wip,
267                Err(e) => {
268                    let default_span = Span::default();
269                    return Err(DeserError::new_reflect(e, input, default_span, source));
270                }
271            };
272
273            // Step 2: Run deserialize_wip
274            let heap_value = match deserialize_wip(wip, input, format) {
275                Ok(val) => val,
276                Err(e) => {
277                    return Err(e);
278                }
279            };
280
281            // Step 3: Materialize
282            match heap_value.materialize() {
283                Ok(val) => Ok(val),
284                Err(e) => {
285                    let default_span = Span::default();
286                    return Err(DeserError::new_reflect(e, input, default_span, source));
287                }
288            }
289        };
290
291        result
292    }
293}
294
295/// Deserialize a value of type `T` from raw input bytes using format `F`.
296///
297/// This function sets up the initial working state and drives the deserialization process,
298/// ensuring that the resulting value is fully materialized and valid.
299pub fn deserialize<'input, 'facet, 'shape, T, F>(
300    input: &'input [u8],
301    format: F,
302) -> Result<T, DeserError<'input, 'shape>>
303where
304    T: Facet<'facet>,
305    F: Format + 'shape,
306    'input: 'facet,
307    'shape: 'input,
308{
309    let mut format_copy = format;
310    deser_impl::deserialize(input, &mut format_copy)
311}
312
313/// Deserializes a working-in-progress value into a fully materialized heap value.
314/// This function drives the parsing loop until the entire input is consumed and the value is complete.
315pub fn deserialize_wip<'input, 'facet, 'shape, F>(
316    mut wip: Partial<'facet, 'shape>,
317    input: &'input [u8],
318    format: &mut F,
319) -> Result<HeapValue<'facet, 'shape>, DeserError<'input, 'shape>>
320where
321    F: Format + 'shape,
322    'input: 'facet,
323    'shape: 'input,
324{
325    // This struct is just a bundle of the state that we need to pass around all the time.
326    let mut runner = StackRunner {
327        original_input: input,
328        input,
329        stack: vec![
330            Instruction::Pop(PopReason::TopLevel),
331            Instruction::Value(ValueReason::TopLevel),
332        ],
333        last_span: Span::new(0, 0),
334        format_source: format.source(),
335        array_indices: Vec::new(),
336        enum_tuple_field_count: None,
337        enum_tuple_current_field: None,
338    };
339
340    macro_rules! next {
341        ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
342            let nd = NextData {
343                start: $runner.last_span.end(), // or supply the appropriate start value if available
344                runner: $runner,
345                wip: $wip,
346            };
347            let (nd, res) = format.next(nd, $expectation);
348            $runner = nd.runner;
349            $wip = nd.wip;
350            let outcome = res.map_err(|span_kind| {
351                $runner.last_span = span_kind.span;
352                $runner.err(span_kind.node)
353            })?;
354            $runner.last_span = outcome.span;
355            $wip = $runner.$method($wip, outcome)?;
356        }};
357    }
358
359    loop {
360        // Note: frames_count() is no longer available in the new Partial API
361        // This was used for debugging/assertions only
362
363        let insn = match runner.stack.pop() {
364            Some(insn) => insn,
365            None => unreachable!("Instruction stack is empty"),
366        };
367
368        trace!("Instruction {:?}", insn.bright_red());
369
370        match insn {
371            Instruction::Pop(reason) => {
372                wip = runner.pop(wip, reason)?;
373
374                if reason == PopReason::TopLevel {
375                    // Exit all nested frames (e.g., from flattened fields) before building
376                    while wip.frame_count() > 1 {
377                        wip.end().map_err(|e| runner.reflect_err(e))?;
378                    }
379                    return wip.build().map_err(|e| runner.reflect_err(e));
380                } else {
381                    wip.end().map_err(|e| runner.reflect_err(e))?;
382                }
383            }
384            Instruction::Value(_why) => {
385                let expectation = match _why {
386                    ValueReason::TopLevel => Expectation::Value,
387                    ValueReason::ObjectVal => Expectation::ObjectVal,
388                };
389                next!(runner, wip, expectation, value);
390            }
391            Instruction::ObjectKeyOrObjectClose => {
392                next!(
393                    runner,
394                    wip,
395                    Expectation::ObjectKeyOrObjectClose,
396                    object_key_or_object_close
397                );
398            }
399            Instruction::ListItemOrListClose => {
400                next!(
401                    runner,
402                    wip,
403                    Expectation::ListItemOrListClose,
404                    list_item_or_list_close
405                );
406            }
407            Instruction::SkipValue => {
408                // Call F::skip to skip over the next value in the input
409                let nd = NextData {
410                    start: runner.last_span.end(),
411                    runner,
412                    wip,
413                };
414                let (nd, res) = format.skip(nd);
415                runner = nd.runner;
416                wip = nd.wip;
417                // Only propagate error, don't modify wip, since skip just advances input
418                let span = res.map_err(|span_kind| {
419                    runner.last_span = span_kind.span;
420                    runner.err(span_kind.node)
421                })?;
422                // do the actual skip
423                runner.last_span = span;
424            }
425        }
426    }
427}
428
429/// Helper function to check if an f64 has no fractional part
430/// This is needed for no-std compatibility where f64::fract() is not available
431#[inline]
432fn has_no_fractional_part(value: f64) -> bool {
433    value == (value as i64) as f64
434}
435
436/// Trait for numeric type conversions
437trait NumericConvert {
438    fn to_i8(&self) -> Option<i8>;
439    fn to_i16(&self) -> Option<i16>;
440    fn to_i32(&self) -> Option<i32>;
441    fn to_i64(&self) -> Option<i64>;
442    fn to_i128(&self) -> Option<i128>;
443    fn to_isize(&self) -> Option<isize>;
444
445    fn to_u8(&self) -> Option<u8>;
446    fn to_u16(&self) -> Option<u16>;
447    fn to_u32(&self) -> Option<u32>;
448    fn to_u64(&self) -> Option<u64>;
449    fn to_u128(&self) -> Option<u128>;
450    fn to_usize(&self) -> Option<usize>;
451
452    fn to_f32(&self) -> Option<f32>;
453    fn to_f64(&self) -> Option<f64>;
454}
455
456impl NumericConvert for u64 {
457    fn to_i8(&self) -> Option<i8> {
458        (*self).try_into().ok()
459    }
460    fn to_i16(&self) -> Option<i16> {
461        (*self).try_into().ok()
462    }
463    fn to_i32(&self) -> Option<i32> {
464        (*self).try_into().ok()
465    }
466    fn to_i64(&self) -> Option<i64> {
467        (*self).try_into().ok()
468    }
469    fn to_i128(&self) -> Option<i128> {
470        Some(*self as i128)
471    }
472    fn to_isize(&self) -> Option<isize> {
473        (*self).try_into().ok()
474    }
475
476    fn to_u8(&self) -> Option<u8> {
477        (*self).try_into().ok()
478    }
479    fn to_u16(&self) -> Option<u16> {
480        (*self).try_into().ok()
481    }
482    fn to_u32(&self) -> Option<u32> {
483        (*self).try_into().ok()
484    }
485    fn to_u64(&self) -> Option<u64> {
486        Some(*self)
487    }
488    fn to_u128(&self) -> Option<u128> {
489        Some(*self as u128)
490    }
491    fn to_usize(&self) -> Option<usize> {
492        (*self).try_into().ok()
493    }
494
495    fn to_f32(&self) -> Option<f32> {
496        Some(*self as f32)
497    }
498    fn to_f64(&self) -> Option<f64> {
499        Some(*self as f64)
500    }
501}
502
503impl NumericConvert for i64 {
504    fn to_i8(&self) -> Option<i8> {
505        (*self).try_into().ok()
506    }
507    fn to_i16(&self) -> Option<i16> {
508        (*self).try_into().ok()
509    }
510    fn to_i32(&self) -> Option<i32> {
511        (*self).try_into().ok()
512    }
513    fn to_i64(&self) -> Option<i64> {
514        Some(*self)
515    }
516    fn to_i128(&self) -> Option<i128> {
517        Some(*self as i128)
518    }
519    fn to_isize(&self) -> Option<isize> {
520        (*self).try_into().ok()
521    }
522
523    fn to_u8(&self) -> Option<u8> {
524        (*self).try_into().ok()
525    }
526    fn to_u16(&self) -> Option<u16> {
527        (*self).try_into().ok()
528    }
529    fn to_u32(&self) -> Option<u32> {
530        (*self).try_into().ok()
531    }
532    fn to_u64(&self) -> Option<u64> {
533        (*self).try_into().ok()
534    }
535    fn to_u128(&self) -> Option<u128> {
536        (*self).try_into().ok()
537    }
538    fn to_usize(&self) -> Option<usize> {
539        (*self).try_into().ok()
540    }
541
542    fn to_f32(&self) -> Option<f32> {
543        Some(*self as f32)
544    }
545    fn to_f64(&self) -> Option<f64> {
546        Some(*self as f64)
547    }
548}
549
550impl NumericConvert for f64 {
551    fn to_i8(&self) -> Option<i8> {
552        if has_no_fractional_part(*self) && *self >= i8::MIN as f64 && *self <= i8::MAX as f64 {
553            Some(*self as i8)
554        } else {
555            None
556        }
557    }
558    fn to_i16(&self) -> Option<i16> {
559        if has_no_fractional_part(*self) && *self >= i16::MIN as f64 && *self <= i16::MAX as f64 {
560            Some(*self as i16)
561        } else {
562            None
563        }
564    }
565    fn to_i32(&self) -> Option<i32> {
566        if has_no_fractional_part(*self) && *self >= i32::MIN as f64 && *self <= i32::MAX as f64 {
567            Some(*self as i32)
568        } else {
569            None
570        }
571    }
572    fn to_i64(&self) -> Option<i64> {
573        if has_no_fractional_part(*self) && *self >= i64::MIN as f64 && *self <= i64::MAX as f64 {
574            Some(*self as i64)
575        } else {
576            None
577        }
578    }
579    fn to_i128(&self) -> Option<i128> {
580        if has_no_fractional_part(*self) && *self >= i128::MIN as f64 && *self <= i128::MAX as f64 {
581            Some(*self as i128)
582        } else {
583            None
584        }
585    }
586    fn to_isize(&self) -> Option<isize> {
587        if has_no_fractional_part(*self) && *self >= isize::MIN as f64 && *self <= isize::MAX as f64
588        {
589            Some(*self as isize)
590        } else {
591            None
592        }
593    }
594
595    fn to_u8(&self) -> Option<u8> {
596        if has_no_fractional_part(*self) && *self >= 0.0 && *self <= u8::MAX as f64 {
597            Some(*self as u8)
598        } else {
599            None
600        }
601    }
602    fn to_u16(&self) -> Option<u16> {
603        if has_no_fractional_part(*self) && *self >= 0.0 && *self <= u16::MAX as f64 {
604            Some(*self as u16)
605        } else {
606            None
607        }
608    }
609    fn to_u32(&self) -> Option<u32> {
610        if has_no_fractional_part(*self) && *self >= 0.0 && *self <= u32::MAX as f64 {
611            Some(*self as u32)
612        } else {
613            None
614        }
615    }
616    fn to_u64(&self) -> Option<u64> {
617        if has_no_fractional_part(*self) && *self >= 0.0 && *self <= u64::MAX as f64 {
618            Some(*self as u64)
619        } else {
620            None
621        }
622    }
623    fn to_u128(&self) -> Option<u128> {
624        if has_no_fractional_part(*self) && *self >= 0.0 && *self <= u128::MAX as f64 {
625            Some(*self as u128)
626        } else {
627            None
628        }
629    }
630    fn to_usize(&self) -> Option<usize> {
631        if has_no_fractional_part(*self) && *self >= 0.0 && *self <= usize::MAX as f64 {
632            Some(*self as usize)
633        } else {
634            None
635        }
636    }
637
638    fn to_f32(&self) -> Option<f32> {
639        Some(*self as f32)
640    }
641    fn to_f64(&self) -> Option<f64> {
642        Some(*self)
643    }
644}
645
646impl NumericConvert for u128 {
647    fn to_i8(&self) -> Option<i8> {
648        (*self).try_into().ok()
649    }
650    fn to_i16(&self) -> Option<i16> {
651        (*self).try_into().ok()
652    }
653    fn to_i32(&self) -> Option<i32> {
654        (*self).try_into().ok()
655    }
656    fn to_i64(&self) -> Option<i64> {
657        (*self).try_into().ok()
658    }
659    fn to_i128(&self) -> Option<i128> {
660        Some(*self as i128)
661    }
662    fn to_isize(&self) -> Option<isize> {
663        (*self).try_into().ok()
664    }
665
666    fn to_u8(&self) -> Option<u8> {
667        (*self).try_into().ok()
668    }
669    fn to_u16(&self) -> Option<u16> {
670        (*self).try_into().ok()
671    }
672    fn to_u32(&self) -> Option<u32> {
673        (*self).try_into().ok()
674    }
675    fn to_u64(&self) -> Option<u64> {
676        (*self).try_into().ok()
677    }
678    fn to_u128(&self) -> Option<u128> {
679        Some(*self)
680    }
681    fn to_usize(&self) -> Option<usize> {
682        (*self).try_into().ok()
683    }
684
685    fn to_f32(&self) -> Option<f32> {
686        Some(*self as f32)
687    }
688    fn to_f64(&self) -> Option<f64> {
689        Some(*self as f64)
690    }
691}
692
693impl NumericConvert for i128 {
694    fn to_i8(&self) -> Option<i8> {
695        (*self).try_into().ok()
696    }
697    fn to_i16(&self) -> Option<i16> {
698        (*self).try_into().ok()
699    }
700    fn to_i32(&self) -> Option<i32> {
701        (*self).try_into().ok()
702    }
703    fn to_i64(&self) -> Option<i64> {
704        (*self).try_into().ok()
705    }
706    fn to_i128(&self) -> Option<i128> {
707        Some(*self)
708    }
709    fn to_isize(&self) -> Option<isize> {
710        (*self).try_into().ok()
711    }
712
713    fn to_u8(&self) -> Option<u8> {
714        (*self).try_into().ok()
715    }
716    fn to_u16(&self) -> Option<u16> {
717        (*self).try_into().ok()
718    }
719    fn to_u32(&self) -> Option<u32> {
720        (*self).try_into().ok()
721    }
722    fn to_u64(&self) -> Option<u64> {
723        (*self).try_into().ok()
724    }
725    fn to_u128(&self) -> Option<u128> {
726        (*self).try_into().ok()
727    }
728    fn to_usize(&self) -> Option<usize> {
729        (*self).try_into().ok()
730    }
731
732    fn to_f32(&self) -> Option<f32> {
733        Some(*self as f32)
734    }
735    fn to_f64(&self) -> Option<f64> {
736        Some(*self as f64)
737    }
738}
739
740#[doc(hidden)]
741/// Maintains the parsing state and context necessary to drive deserialization.
742///
743/// This struct tracks what the parser expects next, manages input position,
744/// and remembers the span of the last processed token to provide accurate error reporting.
745pub struct StackRunner<'input> {
746    /// A version of the input that doesn't advance as we parse.
747    pub original_input: &'input [u8],
748
749    /// The raw input data being deserialized.
750    pub input: &'input [u8],
751
752    /// Stack of parsing instructions guiding the control flow.
753    pub stack: Vec<Instruction>,
754
755    /// Span of the last processed token, for accurate error reporting.
756    pub last_span: Span,
757
758    /// Format source identifier for error reporting
759    pub format_source: &'static str,
760
761    /// Array index tracking - maps depth to current index for arrays
762    pub array_indices: Vec<usize>,
763
764    /// Tuple variant field tracking - number of fields in current enum tuple variant
765    pub enum_tuple_field_count: Option<usize>,
766
767    /// Tuple variant field tracking - current field index being processed
768    pub enum_tuple_current_field: Option<usize>,
769}
770
771impl<'input, 'shape> StackRunner<'input> {
772    /// Convenience function to create a DeserError using the original input and last_span.
773    fn err(&self, kind: DeserErrorKind<'shape>) -> DeserError<'input, 'shape> {
774        DeserError::new(
775            kind,
776            self.original_input,
777            self.last_span,
778            self.format_source,
779        )
780    }
781
782    /// Convenience function to create a DeserError from a ReflectError,
783    /// using the original input and last_span for context.
784    fn reflect_err(&self, err: ReflectError<'shape>) -> DeserError<'input, 'shape> {
785        DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
786    }
787
788    pub fn pop<'facet>(
789        &mut self,
790        mut wip: Partial<'facet, 'shape>,
791        reason: PopReason,
792    ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape>> {
793        trace!(
794            "--- STACK has {:?} {}",
795            self.stack.green(),
796            "(POP)".bright_yellow()
797        );
798        trace!("Popping because {:?}", reason.yellow());
799
800        let container_shape = wip.shape();
801        match container_shape.ty {
802            Type::User(UserType::Struct(sd)) => {
803                let mut has_unset = false;
804
805                trace!("Let's check all fields are initialized");
806                for (index, field) in sd.fields.iter().enumerate() {
807                    let is_set = wip.is_field_set(index).map_err(|err| {
808                        trace!("Error checking field set status: {err:?}");
809                        self.reflect_err(err)
810                    })?;
811                    if !is_set {
812                        if field.flags.contains(FieldFlags::DEFAULT) {
813                            wip.begin_nth_field(index)
814                                .map_err(|e| self.reflect_err(e))?;
815
816                            // Check for field-level default function first, then type-level default
817                            if let Some(field_default_fn) = field.vtable.default_fn {
818                                wip.set_field_default(field_default_fn)
819                                    .map_err(|e| self.reflect_err(e))?;
820                                trace!(
821                                    "Field #{} {} @ {} was set to default value (via field default function)",
822                                    index.yellow(),
823                                    field.name.green(),
824                                    field.offset.blue(),
825                                );
826                            } else if field.shape().is(Characteristic::Default) {
827                                wip.set_default().map_err(|e| self.reflect_err(e))?;
828                                trace!(
829                                    "Field #{} {} @ {} was set to default value (via type default impl)",
830                                    index.yellow(),
831                                    field.name.green(),
832                                    field.offset.blue(),
833                                );
834                            } else {
835                                return Err(self.reflect_err(
836                                    ReflectError::DefaultAttrButNoDefaultImpl {
837                                        shape: field.shape(),
838                                    },
839                                ));
840                            }
841                            wip.end().map_err(|e| self.reflect_err(e))?;
842                        } else {
843                            trace!(
844                                "Field #{} {} @ {} is not initialized",
845                                index.yellow(),
846                                field.name.green(),
847                                field.offset.blue(),
848                            );
849                            has_unset = true;
850                        }
851                    }
852                }
853
854                if has_unset {
855                    if container_shape.has_default_attr() {
856                        // let's allocate and build a default value
857                        let default_val = Partial::alloc_shape(container_shape)
858                            .map_err(|e| self.reflect_err(e))?
859                            .set_default()
860                            .map_err(|e| self.reflect_err(e))?
861                            .build()
862                            .map_err(|e| self.reflect_err(e))?;
863                        let peek = default_val.peek().into_struct().unwrap();
864
865                        for (index, field) in sd.fields.iter().enumerate() {
866                            let is_set = wip.is_field_set(index).map_err(|err| {
867                                trace!("Error checking field set status: {err:?}");
868                                self.reflect_err(err)
869                            })?;
870                            if !is_set {
871                                trace!(
872                                    "Field #{} {} @ {} is being set to default value (from default instance)",
873                                    index.yellow(),
874                                    field.name.green(),
875                                    field.offset.blue(),
876                                );
877                                wip.begin_nth_field(index)
878                                    .map_err(|e| self.reflect_err(e))?;
879                                // Get the field as a Peek from the default value
880                                let def_field = peek.field(index).unwrap();
881                                wip.set_from_peek(&def_field)
882                                    .map_err(|e| self.reflect_err(e))?;
883                                wip.end().map_err(|e| self.reflect_err(e))?;
884                            }
885                        }
886                    } else {
887                        // Find the first uninitialized field to report in the error
888                        for (index, field) in sd.fields.iter().enumerate() {
889                            let is_set = wip.is_field_set(index).map_err(|err| {
890                                trace!("Error checking field set status: {err:?}");
891                                self.reflect_err(err)
892                            })?;
893                            if !is_set {
894                                return Err(self.reflect_err(ReflectError::UninitializedField {
895                                    shape: container_shape,
896                                    field_name: field.name,
897                                }));
898                            }
899                        }
900                    }
901                }
902            }
903            Type::User(UserType::Enum(ed)) => {
904                trace!("Checking if enum is initialized correctly");
905
906                // Check if a variant has been selected
907                if let Some(variant) = wip.selected_variant() {
908                    trace!("Variant {} is selected", variant.name.blue());
909
910                    // Check if all fields in the variant are initialized
911                    if !variant.data.fields.is_empty() {
912                        let mut has_unset = false;
913
914                        for (index, field) in variant.data.fields.iter().enumerate() {
915                            let is_set = wip.is_field_set(index).map_err(|err| {
916                                trace!("Error checking field set status: {err:?}");
917                                self.reflect_err(err)
918                            })?;
919
920                            if !is_set {
921                                if field.flags.contains(FieldFlags::DEFAULT) {
922                                    wip.begin_nth_field(index)
923                                        .map_err(|e| self.reflect_err(e))?;
924
925                                    // Check for field-level default function first, then type-level default
926                                    if let Some(field_default_fn) = field.vtable.default_fn {
927                                        wip.set_field_default(field_default_fn)
928                                            .map_err(|e| self.reflect_err(e))?;
929                                        trace!(
930                                            "Field #{} @ {} in variant {} was set to default value (via field default function)",
931                                            index.yellow(),
932                                            field.offset.blue(),
933                                            variant.name
934                                        );
935                                    } else if field.shape().is(Characteristic::Default) {
936                                        wip.set_default().map_err(|e| self.reflect_err(e))?;
937                                        trace!(
938                                            "Field #{} @ {} in variant {} was set to default value (via type default impl)",
939                                            index.yellow(),
940                                            field.offset.blue(),
941                                            variant.name
942                                        );
943                                    } else {
944                                        return Err(self.reflect_err(
945                                            ReflectError::DefaultAttrButNoDefaultImpl {
946                                                shape: field.shape(),
947                                            },
948                                        ));
949                                    }
950                                    wip.end().map_err(|e| self.reflect_err(e))?;
951                                } else {
952                                    trace!(
953                                        "Field #{} @ {} in variant {} is not initialized",
954                                        index.yellow(),
955                                        field.offset.blue(),
956                                        variant.name
957                                    );
958                                    has_unset = true;
959                                }
960                            }
961                        }
962
963                        if has_unset {
964                            if container_shape.has_default_attr() {
965                                trace!(
966                                    "Enum has DEFAULT attr but variant has uninitialized fields"
967                                );
968                                // Handle similar to struct, allocate and build default value for variant
969                                let default_val = Partial::alloc_shape(container_shape)
970                                    .map_err(|e| self.reflect_err(e))?
971                                    .set_default()
972                                    .map_err(|e| self.reflect_err(e))?
973                                    .build()
974                                    .map_err(|e| self.reflect_err(e))?;
975
976                                let peek = default_val.peek();
977                                let peek_enum =
978                                    peek.into_enum().map_err(|e| self.reflect_err(e))?;
979                                let default_variant = peek_enum
980                                    .active_variant()
981                                    .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
982
983                                if default_variant.name == variant.name {
984                                    // It's the same variant, fill in the missing fields
985                                    for (index, _field) in variant.data.fields.iter().enumerate() {
986                                        let is_set = wip.is_field_set(index).map_err(|err| {
987                                            trace!("Error checking field set status: {err:?}");
988                                            self.reflect_err(err)
989                                        })?;
990                                        if !is_set {
991                                            if let Ok(Some(def_field)) = peek_enum.field(index) {
992                                                wip.begin_nth_field(index)
993                                                    .map_err(|e| self.reflect_err(e))?;
994                                                wip.set_from_peek(&def_field)
995                                                    .map_err(|e| self.reflect_err(e))?;
996                                                wip.end().map_err(|e| self.reflect_err(e))?;
997                                            }
998                                        }
999                                    }
1000                                }
1001                            } else {
1002                                // Find the first uninitialized field to report in the error
1003                                for (index, field) in variant.data.fields.iter().enumerate() {
1004                                    let is_set = wip.is_field_set(index).map_err(|err| {
1005                                        trace!("Error checking field set status: {err:?}");
1006                                        self.reflect_err(err)
1007                                    })?;
1008                                    if !is_set {
1009                                        return Err(self.reflect_err(
1010                                            ReflectError::UninitializedEnumField {
1011                                                shape: container_shape,
1012                                                variant_name: variant.name,
1013                                                field_name: field.name,
1014                                            },
1015                                        ));
1016                                    }
1017                                }
1018                            }
1019                        }
1020                    }
1021                } else if container_shape.has_default_attr() {
1022                    // No variant selected, but enum has default attribute - set to default
1023                    trace!("No variant selected but enum has DEFAULT attr; setting to default");
1024                    let default_val = Partial::alloc_shape(container_shape)
1025                        .map_err(|e| self.reflect_err(e))?
1026                        .set_default()
1027                        .map_err(|e| self.reflect_err(e))?
1028                        .build()
1029                        .map_err(|e| self.reflect_err(e))?;
1030
1031                    let peek = default_val.peek();
1032                    let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
1033                    let default_variant_idx = peek_enum
1034                        .variant_index()
1035                        .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
1036
1037                    // Select the default variant
1038                    wip.select_nth_variant(default_variant_idx)
1039                        .map_err(|e| self.reflect_err(e))?;
1040
1041                    // Copy all fields from default value
1042                    let variant = &ed.variants[default_variant_idx];
1043                    for (index, _field) in variant.data.fields.iter().enumerate() {
1044                        if let Ok(Some(def_field)) = peek_enum.field(index) {
1045                            wip.begin_nth_field(index)
1046                                .map_err(|e| self.reflect_err(e))?;
1047                            wip.set_from_peek(&def_field)
1048                                .map_err(|e| self.reflect_err(e))?;
1049                            wip.end().map_err(|e| self.reflect_err(e))?;
1050                        }
1051                    }
1052                }
1053            }
1054            _ => {
1055                trace!(
1056                    "Thing being popped is not a container I guess (it's a {}, innermost is {})",
1057                    wip.shape(),
1058                    wip.innermost_shape()
1059                );
1060            }
1061        }
1062        Ok(wip)
1063    }
1064
1065    /// Internal common handler for GotScalar outcome, to deduplicate code.
1066    /// Helper to set numeric values with type conversion
1067    fn set_numeric_value<'facet>(
1068        &self,
1069        wip: &mut Partial<'facet, 'shape>,
1070        value: &dyn NumericConvert,
1071    ) -> Result<(), DeserError<'input, 'shape>>
1072    where
1073        'input: 'facet,
1074    {
1075        let shape = wip.innermost_shape();
1076
1077        let Type::Primitive(PrimitiveType::Numeric(numeric_type)) = shape.ty else {
1078            return Err(self.err(DeserErrorKind::UnsupportedType {
1079                got: shape,
1080                wanted: "numeric type",
1081            }));
1082        };
1083
1084        // Get the size from the layout
1085        let size_bytes = shape
1086            .layout
1087            .sized_layout()
1088            .map_err(|_| {
1089                self.err(DeserErrorKind::UnsupportedType {
1090                    got: shape,
1091                    wanted: "sized numeric type",
1092                })
1093            })?
1094            .size();
1095
1096        if matches!(shape.def, Def::Scalar) {
1097            // Helper closure to convert and set numeric value
1098            macro_rules! convert_and_set {
1099                ($converter:expr, $target_type:expr) => {{
1100                    let converted = $converter.ok_or_else(|| {
1101                        self.err(DeserErrorKind::NumericConversion {
1102                            from: "numeric",
1103                            to: $target_type,
1104                        })
1105                    })?;
1106                    wip.set(converted).map_err(|e| self.reflect_err(e))?;
1107                }};
1108            }
1109
1110            match numeric_type {
1111                NumericType::Integer { signed } => {
1112                    // First check if the shape is specifically usize or isize
1113                    if !signed && shape.is_type::<usize>() {
1114                        convert_and_set!(value.to_usize(), "usize")
1115                    } else if signed && shape.is_type::<isize>() {
1116                        convert_and_set!(value.to_isize(), "isize")
1117                    } else {
1118                        // Then check by size
1119                        match (size_bytes, signed) {
1120                            (1, true) => convert_and_set!(value.to_i8(), "i8"),
1121                            (2, true) => convert_and_set!(value.to_i16(), "i16"),
1122                            (4, true) => convert_and_set!(value.to_i32(), "i32"),
1123                            (8, true) => convert_and_set!(value.to_i64(), "i64"),
1124                            (16, true) => convert_and_set!(value.to_i128(), "i128"),
1125                            (1, false) => convert_and_set!(value.to_u8(), "u8"),
1126                            (2, false) => convert_and_set!(value.to_u16(), "u16"),
1127                            (4, false) => convert_and_set!(value.to_u32(), "u32"),
1128                            (8, false) => convert_and_set!(value.to_u64(), "u64"),
1129                            (16, false) => convert_and_set!(value.to_u128(), "u128"),
1130                            _ => {
1131                                return Err(self.err(DeserErrorKind::NumericConversion {
1132                                    from: "numeric",
1133                                    to: if signed {
1134                                        "unknown signed integer size"
1135                                    } else {
1136                                        "unknown unsigned integer size"
1137                                    },
1138                                }));
1139                            }
1140                        }
1141                    }
1142                }
1143                NumericType::Float => match size_bytes {
1144                    4 => convert_and_set!(value.to_f32(), "f32"),
1145                    8 => convert_and_set!(value.to_f64(), "f64"),
1146                    _ => {
1147                        return Err(self.err(DeserErrorKind::NumericConversion {
1148                            from: "numeric",
1149                            to: "unknown float size",
1150                        }));
1151                    }
1152                },
1153            }
1154        } else {
1155            // Not a scalar def - cannot convert
1156            return Err(self.err(DeserErrorKind::UnsupportedType {
1157                got: shape,
1158                wanted: "scalar type",
1159            }));
1160        }
1161
1162        Ok(())
1163    }
1164
1165    fn handle_scalar<'facet>(
1166        &self,
1167        wip: &mut Partial<'facet, 'shape>,
1168        scalar: Scalar<'input>,
1169    ) -> Result<(), DeserError<'input, 'shape>>
1170    where
1171        'input: 'facet, // 'input outlives 'facet
1172    {
1173        match scalar {
1174            Scalar::String(cow) => {
1175                match wip.innermost_shape().ty {
1176                    Type::User(UserType::Enum(_)) => {
1177                        if wip.selected_variant().is_some() {
1178                            // If we already have a variant selected, just put the string
1179                            wip.set(cow).map_err(|e| self.reflect_err(e))?;
1180                        } else {
1181                            // Try to select the variant
1182                            match wip.find_variant(&cow) {
1183                                Some((variant_index, _)) => {
1184                                    wip.select_nth_variant(variant_index)
1185                                        .map_err(|e| self.reflect_err(e))?;
1186                                }
1187                                None => {
1188                                    return Err(self.err(DeserErrorKind::NoSuchVariant {
1189                                        name: cow.to_string(),
1190                                        enum_shape: wip.innermost_shape(),
1191                                    }));
1192                                }
1193                            }
1194                        }
1195                    }
1196                    Type::Pointer(PointerType::Reference(_))
1197                        if wip.innermost_shape().is_type::<&str>() =>
1198                    {
1199                        // This is for handling the &str type
1200                        // The Cow may be Borrowed (we may have an owned string but need a &str)
1201                        match cow {
1202                            Cow::Borrowed(s) => wip.set(s).map_err(|e| self.reflect_err(e))?,
1203                            Cow::Owned(s) => wip.set(s).map_err(|e| self.reflect_err(e))?,
1204                        }; // Add semicolon to ignore the return value
1205                    }
1206                    _ => {
1207                        // Check if this is a scalar type that can be parsed from a string
1208                        let shape = wip.innermost_shape();
1209                        if matches!(shape.def, Def::Scalar) {
1210                            // Try parse_from_str for scalar types that might parse from strings
1211                            // (like IpAddr, UUID, Path, etc.)
1212                            match wip.parse_from_str(cow.as_ref()) {
1213                                Ok(_) => {
1214                                    // Successfully parsed
1215                                }
1216                                Err(parse_err) => {
1217                                    // Parsing failed - check if it's because parse isn't supported
1218                                    // or if parsing actually failed
1219                                    match parse_err {
1220                                        ReflectError::OperationFailed {
1221                                            shape: _,
1222                                            operation,
1223                                        } if operation.contains("does not support parsing") => {
1224                                            // Type doesn't have a parse function, try direct conversion
1225                                            wip.set(cow.to_string())
1226                                                .map_err(|e| self.reflect_err(e))?;
1227                                        }
1228                                        _ => {
1229                                            // Actual parsing failure
1230                                            return Err(self.err(DeserErrorKind::ReflectError(
1231                                                ReflectError::OperationFailed {
1232                                                    shape,
1233                                                    operation: "Failed to parse string value",
1234                                                },
1235                                            )));
1236                                        }
1237                                    }
1238                                }
1239                            }
1240                        } else {
1241                            // Not a scalar, just set as String
1242                            wip.set(cow.to_string()).map_err(|e| self.reflect_err(e))?;
1243                        }
1244                    }
1245                }
1246            }
1247            Scalar::U64(value) => {
1248                self.set_numeric_value(wip, &value)?;
1249            }
1250            Scalar::I64(value) => {
1251                self.set_numeric_value(wip, &value)?;
1252            }
1253            Scalar::F64(value) => {
1254                self.set_numeric_value(wip, &value)?;
1255            }
1256            Scalar::U128(value) => {
1257                self.set_numeric_value(wip, &value)?;
1258            }
1259            Scalar::I128(value) => {
1260                self.set_numeric_value(wip, &value)?;
1261            }
1262            Scalar::Bool(value) => {
1263                wip.set(value).map_err(|e| self.reflect_err(e))?;
1264            }
1265            Scalar::Null => {
1266                wip.set_default().map_err(|e| self.reflect_err(e))?;
1267            }
1268        }
1269        Ok(())
1270    }
1271
1272    /// Handle value parsing
1273    fn value<'facet>(
1274        &mut self,
1275        mut wip: Partial<'facet, 'shape>,
1276        outcome: Spanned<Outcome<'input>>,
1277    ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape>>
1278    where
1279        'input: 'facet, // 'input must outlive 'facet
1280    {
1281        trace!(
1282            "--- STACK has {:?} {}",
1283            self.stack.green(),
1284            "(VALUE)".bright_yellow()
1285        );
1286
1287        let original_shape = wip.shape();
1288        trace!("Handling value of type {}", original_shape.blue());
1289
1290        // Handle null values
1291        if matches!(outcome.node, Outcome::Scalar(Scalar::Null)) {
1292            wip.set_default().map_err(|e| self.reflect_err(e))?;
1293            return Ok(wip);
1294        }
1295
1296        // Resolve the innermost value to deserialize
1297        let mut smart_pointer_begun = false;
1298        loop {
1299            trace!("  Loop iteration: current shape is {}", wip.shape().blue());
1300            if matches!(wip.shape().def, Def::Option(_)) {
1301                trace!("  Starting Some(_) option for {}", wip.shape().blue());
1302                wip.begin_some().map_err(|e| self.reflect_err(e))?;
1303                self.stack.push(Instruction::Pop(PopReason::Some));
1304            } else if let Def::Pointer(inner) = wip.shape().def {
1305                // Check if we've already begun this smart pointer
1306                // (this can happen with slice pointees where the shape doesn't change)
1307                if smart_pointer_begun {
1308                    break;
1309                }
1310                if let Some(pointee) = inner.pointee() {
1311                    trace!(
1312                        "  Starting smart pointer for {} (pointee is {})",
1313                        wip.shape().blue(),
1314                        pointee.yellow(),
1315                    );
1316                } else {
1317                    trace!(
1318                        "  Starting smart pointer for {} (no pointee)",
1319                        wip.shape().blue()
1320                    );
1321                }
1322                trace!("  About to call begin_smart_ptr()");
1323                wip.begin_smart_ptr().map_err(|e| self.reflect_err(e))?;
1324                trace!(
1325                    "  After begin_smart_ptr(), shape is now {}",
1326                    wip.shape().blue()
1327                );
1328                self.stack.push(Instruction::Pop(PopReason::SmartPointer));
1329                smart_pointer_begun = true;
1330            } else if let Some(inner_fn) = wip.shape().inner {
1331                let inner = inner_fn();
1332                trace!(
1333                    "  Starting wrapped value for {} (inner is {})",
1334                    wip.shape().blue(),
1335                    inner.yellow()
1336                );
1337                wip.begin_inner().map_err(|e| self.reflect_err(e))?;
1338                self.stack.push(Instruction::Pop(PopReason::Wrapper));
1339            } else {
1340                break;
1341            }
1342        }
1343
1344        if wip.shape() != original_shape {
1345            trace!(
1346                "Handling shape {} as innermost {}",
1347                original_shape.blue(),
1348                wip.shape().yellow()
1349            );
1350        }
1351
1352        match outcome.node {
1353            Outcome::Scalar(s) => {
1354                trace!("Parsed scalar value: {}", s.cyan());
1355                self.handle_scalar(&mut wip, s)?;
1356            }
1357            Outcome::ListStarted => {
1358                let shape = wip.innermost_shape();
1359
1360                // First check if this is a tuple struct (including empty tuples)
1361                if let Type::User(UserType::Struct(st)) = shape.ty {
1362                    if st.kind == StructKind::Tuple {
1363                        trace!(
1364                            "Array starting for tuple struct ({}) with {} fields!",
1365                            shape.blue(),
1366                            st.fields.len()
1367                        );
1368
1369                        // Non-empty tuples need to process list events
1370                        trace!("Beginning pushback");
1371                        self.stack.push(Instruction::ListItemOrListClose);
1372                        return Ok(wip);
1373                    }
1374                }
1375
1376                match shape.def {
1377                    Def::Array(_) => {
1378                        trace!("Array starting for array ({})!", shape.blue());
1379                        // We'll initialize the array elements one by one through the pushback workflow
1380                        // Don't call put_default, as arrays need different initialization
1381                    }
1382                    Def::Slice(_) => {
1383                        trace!("Array starting for slice ({})!", shape.blue());
1384                    }
1385                    Def::List(_) => {
1386                        trace!("Array starting for list ({})!", shape.blue());
1387                        wip.set_default().map_err(|e| self.reflect_err(e))?;
1388                    }
1389                    _ => {
1390                        // Check if we're building a smart pointer slice
1391                        if matches!(shape.def, Def::Pointer(_)) && smart_pointer_begun {
1392                            trace!("Array starting for smart pointer slice ({})!", shape.blue());
1393                            wip.begin_list().map_err(|e| self.reflect_err(e))?;
1394                        } else if let Type::User(user_ty) = shape.ty {
1395                            // For non-collection types, check the Type enum
1396                            match user_ty {
1397                                UserType::Enum(_) => {
1398                                    trace!("Array starting for enum ({})!", shape.blue());
1399                                    // Check if we have a tuple variant selected
1400                                    if let Some(variant) = wip.selected_variant() {
1401                                        use facet_core::StructKind;
1402                                        if variant.data.kind == StructKind::Tuple {
1403                                            // For tuple variants, we'll handle array elements as tuple fields
1404                                            // Initialize tuple field tracking
1405                                            self.enum_tuple_field_count =
1406                                                Some(variant.data.fields.len());
1407                                            self.enum_tuple_current_field = Some(0);
1408                                        } else {
1409                                            return Err(self.err(DeserErrorKind::UnsupportedType {
1410                                                got: shape,
1411                                                wanted: "tuple variant for array deserialization",
1412                                            }));
1413                                        }
1414                                    } else {
1415                                        return Err(self.err(DeserErrorKind::UnsupportedType {
1416                                            got: shape,
1417                                            wanted: "enum with variant selected",
1418                                        }));
1419                                    }
1420                                }
1421                                UserType::Struct(_) => {
1422                                    // Regular struct shouldn't be parsed from array
1423                                    // (Tuples are already handled above)
1424                                    return Err(self.err(DeserErrorKind::UnsupportedType {
1425                                        got: shape,
1426                                        wanted: "array, list, tuple, or slice",
1427                                    }));
1428                                }
1429                                _ => {
1430                                    return Err(self.err(DeserErrorKind::UnsupportedType {
1431                                        got: shape,
1432                                        wanted: "array, list, tuple, or slice",
1433                                    }));
1434                                }
1435                            }
1436                        } else {
1437                            return Err(self.err(DeserErrorKind::UnsupportedType {
1438                                got: shape,
1439                                wanted: "array, list, tuple, or slice",
1440                            }));
1441                        }
1442                    }
1443                }
1444                trace!("Beginning pushback");
1445                self.stack.push(Instruction::ListItemOrListClose);
1446
1447                // Only call begin_list() for actual lists, not arrays
1448                match shape.def {
1449                    Def::List(_) => {
1450                        wip.begin_list().map_err(|e| self.reflect_err(e))?;
1451                    }
1452                    Def::Array(_) => {
1453                        // Arrays don't need begin_list()
1454                        // Initialize index tracking for this array
1455                        self.array_indices.push(0);
1456                    }
1457                    Def::Slice(_) => {
1458                        // Slices don't need begin_list()
1459                        // They will be populated element by element
1460                    }
1461                    _ => {
1462                        // For other types like tuples, no special initialization needed
1463                    }
1464                }
1465            }
1466            Outcome::ListEnded => {
1467                trace!("List closing");
1468                // Clean up array index tracking if this was an array
1469                let shape = wip.shape();
1470                if matches!(shape.def, Def::Array(_)) {
1471                    self.array_indices.pop();
1472                }
1473                wip.end().map_err(|e| self.reflect_err(e))?;
1474            }
1475            Outcome::ObjectStarted => {
1476                let shape = wip.shape();
1477                match shape.def {
1478                    Def::Map(_md) => {
1479                        trace!("Object starting for map value ({})!", shape.blue());
1480                        wip.begin_map().map_err(|e| self.reflect_err(e))?;
1481                    }
1482                    _ => {
1483                        // For non-collection types, check the Type enum
1484                        if let Type::User(user_ty) = shape.ty {
1485                            match user_ty {
1486                                UserType::Enum(_) => {
1487                                    trace!("Object starting for enum value ({})!", shape.blue());
1488                                    // nothing to do here
1489                                }
1490                                UserType::Struct(_) => {
1491                                    trace!("Object starting for struct value ({})!", shape.blue());
1492                                    // nothing to do here
1493                                }
1494                                _ => {
1495                                    return Err(self.err(DeserErrorKind::UnsupportedType {
1496                                        got: shape,
1497                                        wanted: "map, enum, or struct",
1498                                    }));
1499                                }
1500                            }
1501                        } else if let Type::User(UserType::Struct(struct_type)) = shape.ty {
1502                            if struct_type.kind == StructKind::Tuple {
1503                                // This could be a tuple that was serialized as an object
1504                                // Despite this being unusual, we'll handle it here for robustness
1505                                trace!(
1506                                    "Object starting for tuple ({}) with {} fields - unusual but handling",
1507                                    shape.blue(),
1508                                    struct_type.fields.len()
1509                                );
1510                                // Tuples are treated as structs
1511                            }
1512                        } else {
1513                            return Err(self.err(DeserErrorKind::UnsupportedType {
1514                                got: shape,
1515                                wanted: "map, enum, struct, or tuple",
1516                            }));
1517                        }
1518                    }
1519                }
1520
1521                self.stack.push(Instruction::ObjectKeyOrObjectClose);
1522            }
1523            Outcome::ObjectEnded => todo!(),
1524        }
1525        Ok(wip)
1526    }
1527
1528    fn object_key_or_object_close<'facet>(
1529        &mut self,
1530        mut wip: Partial<'facet, 'shape>,
1531        outcome: Spanned<Outcome<'input>>,
1532    ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape>>
1533    where
1534        'input: 'facet,
1535    {
1536        trace!(
1537            "STACK: {:?} {}",
1538            self.stack.green(),
1539            "(OK/OC)".bright_yellow()
1540        );
1541        match outcome.node {
1542            Outcome::Scalar(Scalar::String(key)) => {
1543                trace!("Parsed object key: {}", key.cyan());
1544
1545                let mut ignore = false;
1546                let mut needs_pop = true;
1547                let mut handled_by_flatten = false;
1548
1549                let shape = wip.innermost_shape();
1550                match shape.ty {
1551                    Type::User(UserType::Struct(sd)) => {
1552                        // First try to find a direct field match
1553                        if let Some(index) = wip.field_index(&key) {
1554                            trace!("It's a struct field");
1555                            wip.begin_nth_field(index)
1556                                .map_err(|e| self.reflect_err(e))?;
1557                        } else {
1558                            trace!(
1559                                "Did not find direct field match in innermost shape {}",
1560                                shape.blue()
1561                            );
1562
1563                            // Check for flattened fields
1564                            let mut found_in_flatten = false;
1565                            for (index, field) in sd.fields.iter().enumerate() {
1566                                if field.flags.contains(FieldFlags::FLATTEN) {
1567                                    trace!("Found flattened field #{index}");
1568                                    // Enter the flattened field
1569                                    wip.begin_nth_field(index)
1570                                        .map_err(|e| self.reflect_err(e))?;
1571
1572                                    // Check if this flattened field has the requested key
1573                                    if let Some(subfield_index) = wip.field_index(&key) {
1574                                        trace!("Found key {key} in flattened field");
1575                                        wip.begin_nth_field(subfield_index)
1576                                            .map_err(|e| self.reflect_err(e))?;
1577                                        found_in_flatten = true;
1578                                        handled_by_flatten = true;
1579                                        break;
1580                                    } else if let Some((_variant_index, _variant)) =
1581                                        wip.find_variant(&key)
1582                                    {
1583                                        trace!("Found key {key} in flattened field");
1584                                        wip.select_variant_named(&key)
1585                                            .map_err(|e| self.reflect_err(e))?;
1586                                        found_in_flatten = true;
1587                                        break;
1588                                    } else {
1589                                        // Key not in this flattened field, go back up
1590                                        wip.end().map_err(|e| self.reflect_err(e))?;
1591                                    }
1592                                }
1593                            }
1594
1595                            if !found_in_flatten {
1596                                if wip.shape().has_deny_unknown_fields_attr() {
1597                                    trace!(
1598                                        "It's not a struct field AND we're denying unknown fields"
1599                                    );
1600                                    return Err(self.err(DeserErrorKind::UnknownField {
1601                                        field_name: key.to_string(),
1602                                        shape: wip.shape(),
1603                                    }));
1604                                } else {
1605                                    trace!(
1606                                        "It's not a struct field and we're ignoring unknown fields"
1607                                    );
1608                                    ignore = true;
1609                                }
1610                            }
1611                        }
1612                    }
1613                    Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
1614                        Some((index, variant)) => {
1615                            trace!(
1616                                "Selecting variant {}::{}",
1617                                wip.shape().blue(),
1618                                variant.name.yellow(),
1619                            );
1620                            wip.select_nth_variant(index)
1621                                .map_err(|e| self.reflect_err(e))?;
1622
1623                            // Let's see what's in the variant — if it's tuple-like with only one field, we want to push field 0
1624                            if matches!(variant.data.kind, StructKind::Tuple)
1625                                && variant.data.fields.len() == 1
1626                            {
1627                                trace!(
1628                                    "Tuple variant {}::{} encountered, pushing field 0",
1629                                    wip.shape().blue(),
1630                                    variant.name.yellow()
1631                                );
1632                                wip.begin_nth_field(0).map_err(|e| self.reflect_err(e))?;
1633                                self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1634                            }
1635
1636                            needs_pop = false;
1637                        }
1638                        None => {
1639                            if let Some(_variant_index) = wip.selected_variant() {
1640                                trace!(
1641                                    "Already have a variant selected, treating {} as struct field of {}::{}",
1642                                    key,
1643                                    wip.shape().blue(),
1644                                    wip.selected_variant().unwrap().name.yellow(),
1645                                );
1646                                // Try to find the field index of the key within the selected variant
1647                                if let Some(index) = wip.field_index(&key) {
1648                                    trace!("Found field {} in selected variant", key.blue());
1649                                    wip.begin_nth_field(index)
1650                                        .map_err(|e| self.reflect_err(e))?;
1651                                } else if wip.shape().has_deny_unknown_fields_attr() {
1652                                    trace!("Unknown field in variant and denying unknown fields");
1653                                    return Err(self.err(DeserErrorKind::UnknownField {
1654                                        field_name: key.to_string(),
1655                                        shape: wip.shape(),
1656                                    }));
1657                                } else {
1658                                    trace!(
1659                                        "Ignoring unknown field '{}' in variant '{}::{}'",
1660                                        key,
1661                                        wip.shape(),
1662                                        wip.selected_variant().unwrap().name
1663                                    );
1664                                    ignore = true;
1665                                }
1666                            } else {
1667                                return Err(self.err(DeserErrorKind::NoSuchVariant {
1668                                    name: key.to_string(),
1669                                    enum_shape: wip.shape(),
1670                                }));
1671                            }
1672                        }
1673                    },
1674                    _ => {
1675                        // Check if it's a map
1676                        if let Def::Map(map_def) = shape.def {
1677                            wip.begin_key().map_err(|e| self.reflect_err(e))?;
1678
1679                            // Check if the map key type is transparent (has an inner shape)
1680                            let key_shape = map_def.k();
1681                            if key_shape.inner.is_some() {
1682                                // For transparent types, we need to navigate into the inner type
1683                                // The inner type should be String for JSON object keys
1684                                // Use begin_inner for consistency with begin_* naming convention
1685                                wip.begin_inner().map_err(|e| self.reflect_err(e))?;
1686                                wip.set(key.to_string()).map_err(|e| self.reflect_err(e))?;
1687                                wip.end().map_err(|e| self.reflect_err(e))?; // End inner
1688                            } else {
1689                                // For non-transparent types, set the string directly
1690                                wip.set(key.to_string()).map_err(|e| self.reflect_err(e))?;
1691                            }
1692
1693                            wip.end().map_err(|e| self.reflect_err(e))?; // Complete the key frame
1694                            wip.begin_value().map_err(|e| self.reflect_err(e))?;
1695                        } else {
1696                            return Err(self.err(DeserErrorKind::Unimplemented(
1697                                "object key for non-struct/map",
1698                            )));
1699                        }
1700                    }
1701                }
1702
1703                self.stack.push(Instruction::ObjectKeyOrObjectClose);
1704                if ignore {
1705                    self.stack.push(Instruction::SkipValue);
1706                } else {
1707                    if needs_pop && !handled_by_flatten {
1708                        trace!("Pushing Pop insn to stack (ObjectVal)");
1709                        self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1710                    } else if handled_by_flatten {
1711                        // For flattened fields, we only need one pop for the field itself.
1712                        // The flattened struct should remain active until the outer object is finished.
1713                        trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1714                        self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1715                    }
1716                    self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1717                }
1718                Ok(wip)
1719            }
1720            Outcome::ObjectEnded => {
1721                trace!("Object closing");
1722                Ok(wip)
1723            }
1724            _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1725                got: outcome.node.into_owned(),
1726                wanted: "scalar or object close",
1727            })),
1728        }
1729    }
1730
1731    fn list_item_or_list_close<'facet>(
1732        &mut self,
1733        mut wip: Partial<'facet, 'shape>,
1734        outcome: Spanned<Outcome<'input>>,
1735    ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape>>
1736    where
1737        'input: 'facet,
1738    {
1739        trace!(
1740            "--- STACK has {:?} {}",
1741            self.stack.green(),
1742            "(LI/LC)".bright_yellow()
1743        );
1744        match outcome.node {
1745            Outcome::ListEnded => {
1746                trace!("List close");
1747                // Clean up array index tracking if this was an array
1748                let shape = wip.shape();
1749                if matches!(shape.def, Def::Array(_)) {
1750                    self.array_indices.pop();
1751                }
1752
1753                // Clean up enum tuple variant tracking if this was an enum tuple
1754                if let Type::User(UserType::Enum(_)) = shape.ty {
1755                    if self.enum_tuple_field_count.is_some() {
1756                        trace!("Enum tuple variant list ended");
1757                        self.enum_tuple_field_count = None;
1758                        self.enum_tuple_current_field = None;
1759                    }
1760                }
1761
1762                // Special case: if we're at an empty tuple, we've successfully parsed it
1763                if let Type::User(UserType::Struct(st)) = shape.ty {
1764                    if st.kind == StructKind::Tuple && st.fields.is_empty() {
1765                        trace!("Empty tuple parsed from []");
1766                        // The empty tuple is complete - no fields to initialize
1767                    }
1768                }
1769
1770                // Don't end the list here - let the Pop instruction handle it
1771                Ok(wip)
1772            }
1773            _ => {
1774                self.stack.push(Instruction::ListItemOrListClose);
1775                self.stack.push(Instruction::Pop(PopReason::ListVal));
1776
1777                trace!(
1778                    "Expecting list item, doing a little push before doing value with outcome {}",
1779                    outcome.magenta()
1780                );
1781                trace!("Before push, wip.shape is {}", wip.shape().blue());
1782
1783                // Different handling for arrays vs lists
1784                let shape = wip.shape();
1785                match shape.def {
1786                    Def::Array(ad) => {
1787                        // Arrays use the last index in our tracking vector
1788                        if let Some(current_index) = self.array_indices.last().copied() {
1789                            // Check bounds
1790                            if current_index >= ad.n {
1791                                return Err(self.err(DeserErrorKind::ArrayOverflow {
1792                                    shape,
1793                                    max_len: ad.n,
1794                                }));
1795                            }
1796
1797                            // Set this array element
1798                            wip.begin_nth_element(current_index)
1799                                .map_err(|e| self.reflect_err(e))?;
1800
1801                            // Increment the index for next time
1802                            if let Some(last) = self.array_indices.last_mut() {
1803                                *last += 1;
1804                            }
1805                        } else {
1806                            // This shouldn't happen if we properly initialize in ListStarted
1807                            return Err(self.err(DeserErrorKind::Unimplemented(
1808                                "Array index tracking not initialized",
1809                            )));
1810                        }
1811                    }
1812                    Def::List(_) => {
1813                        wip.begin_list_item().map_err(|e| self.reflect_err(e))?;
1814                    }
1815                    _ => {
1816                        // Check if this is a smart pointer with slice pointee
1817                        if matches!(shape.def, Def::Pointer(_)) {
1818                            trace!("List item for smart pointer slice");
1819                            wip.begin_list_item().map_err(|e| self.reflect_err(e))?;
1820                        }
1821                        // Check if this is an enum tuple variant
1822                        else if let Type::User(UserType::Enum(_)) = shape.ty {
1823                            if let (Some(field_count), Some(current_field)) =
1824                                (self.enum_tuple_field_count, self.enum_tuple_current_field)
1825                            {
1826                                if current_field >= field_count {
1827                                    // Too many elements for this tuple variant
1828                                    return Err(self.err(DeserErrorKind::ArrayOverflow {
1829                                        shape,
1830                                        max_len: field_count,
1831                                    }));
1832                                }
1833
1834                                // Process this tuple field
1835                                wip.begin_nth_enum_field(current_field)
1836                                    .map_err(|e| self.reflect_err(e))?;
1837
1838                                // Advance to next field
1839                                self.enum_tuple_current_field = Some(current_field + 1);
1840                            } else {
1841                                return Err(self.err(DeserErrorKind::UnsupportedType {
1842                                    got: shape,
1843                                    wanted: "enum with tuple variant selected",
1844                                }));
1845                            }
1846                        }
1847                        // Check if this is a tuple
1848                        else if let Type::User(UserType::Struct(struct_type)) = shape.ty {
1849                            if struct_type.kind == StructKind::Tuple {
1850                                // Tuples use field indexing
1851                                // Find the next uninitialized field
1852                                let mut field_index = None;
1853                                for i in 0..struct_type.fields.len() {
1854                                    if !wip.is_field_set(i).map_err(|e| self.reflect_err(e))? {
1855                                        field_index = Some(i);
1856                                        break;
1857                                    }
1858                                }
1859
1860                                if let Some(idx) = field_index {
1861                                    wip.begin_nth_field(idx).map_err(|e| self.reflect_err(e))?;
1862                                } else {
1863                                    // All fields are set, this is too many elements
1864                                    return Err(self.err(DeserErrorKind::ArrayOverflow {
1865                                        shape,
1866                                        max_len: struct_type.fields.len(),
1867                                    }));
1868                                }
1869                            } else {
1870                                // Not a tuple struct
1871                                return Err(self.err(DeserErrorKind::UnsupportedType {
1872                                    got: shape,
1873                                    wanted: "array, list, or tuple",
1874                                }));
1875                            }
1876                        } else {
1877                            // Not a struct type at all
1878                            return Err(self.err(DeserErrorKind::UnsupportedType {
1879                                got: shape,
1880                                wanted: "array, list, or tuple",
1881                            }));
1882                        }
1883                    }
1884                }
1885
1886                trace!(" After push, wip.shape is {}", wip.shape().cyan());
1887
1888                // Special handling: if we're now at an empty tuple and we see a list start,
1889                // we can handle the flexible coercion from []
1890                if matches!(outcome.node, Outcome::ListStarted) {
1891                    if let Type::User(UserType::Struct(st)) = wip.shape().ty {
1892                        if st.kind == StructKind::Tuple && st.fields.is_empty() {
1893                            trace!(
1894                                "Empty tuple field with list start - initializing empty tuple and expecting immediate close"
1895                            );
1896                            // Initialize the empty tuple with default value since it has no fields to fill
1897                            wip.set_default().map_err(|e| self.reflect_err(e))?;
1898                            // Continue processing - we still need to handle the list close
1899                        }
1900                    }
1901                }
1902
1903                wip = self.value(wip, outcome)?;
1904                Ok(wip)
1905            }
1906        }
1907    }
1908}