facet_deserialize/
lib.rs

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