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