facet_deserialize/
lib.rs

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