facet_format/
deserializer.rs

1extern crate alloc;
2
3use alloc::borrow::Cow;
4use alloc::format;
5use alloc::string::String;
6use core::fmt;
7
8use facet_core::{
9    Def, Facet, KnownPointer, NumericType, PrimitiveType, StructKind, Type, UserType,
10};
11use facet_reflect::{HeapValue, Partial, ReflectError, is_spanned_shape};
12
13use crate::{
14    ContainerKind, FieldLocationHint, FormatParser, ParseEvent, ScalarTypeHint, ScalarValue,
15};
16
17/// Generic deserializer that drives a format-specific parser directly into `Partial`.
18///
19/// The const generic `BORROW` controls whether string data can be borrowed:
20/// - `BORROW=true`: strings without escapes are borrowed from input
21/// - `BORROW=false`: all strings are owned
22pub struct FormatDeserializer<'input, const BORROW: bool, P> {
23    parser: P,
24    /// The span of the most recently consumed event (for error reporting).
25    last_span: Option<facet_reflect::Span>,
26    _marker: core::marker::PhantomData<&'input ()>,
27}
28
29impl<'input, P> FormatDeserializer<'input, true, P> {
30    /// Create a new deserializer that can borrow strings from input.
31    pub const fn new(parser: P) -> Self {
32        Self {
33            parser,
34            last_span: None,
35            _marker: core::marker::PhantomData,
36        }
37    }
38}
39
40impl<'input, P> FormatDeserializer<'input, false, P> {
41    /// Create a new deserializer that produces owned strings.
42    pub const fn new_owned(parser: P) -> Self {
43        Self {
44            parser,
45            last_span: None,
46            _marker: core::marker::PhantomData,
47        }
48    }
49}
50
51impl<'input, const BORROW: bool, P> FormatDeserializer<'input, BORROW, P> {
52    /// Consume the facade and return the underlying parser.
53    pub fn into_inner(self) -> P {
54        self.parser
55    }
56
57    /// Borrow the inner parser mutably.
58    pub fn parser_mut(&mut self) -> &mut P {
59        &mut self.parser
60    }
61}
62
63impl<'input, P> FormatDeserializer<'input, true, P>
64where
65    P: FormatParser<'input>,
66{
67    /// Deserialize the next value in the stream into `T`, allowing borrowed strings.
68    pub fn deserialize<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
69    where
70        T: Facet<'input>,
71    {
72        let wip: Partial<'input, true> =
73            Partial::alloc::<T>().map_err(DeserializeError::reflect)?;
74        let partial = self.deserialize_into(wip)?;
75        let heap_value: HeapValue<'input, true> =
76            partial.build().map_err(DeserializeError::reflect)?;
77        heap_value
78            .materialize::<T>()
79            .map_err(DeserializeError::reflect)
80    }
81
82    /// Deserialize the next value in the stream into `T` (for backward compatibility).
83    pub fn deserialize_root<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
84    where
85        T: Facet<'input>,
86    {
87        self.deserialize()
88    }
89}
90
91impl<'input, P> FormatDeserializer<'input, false, P>
92where
93    P: FormatParser<'input>,
94{
95    /// Deserialize the next value in the stream into `T`, using owned strings.
96    pub fn deserialize<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
97    where
98        T: Facet<'static>,
99    {
100        // SAFETY: alloc_owned produces Partial<'static, false>, but our deserializer
101        // expects 'input. Since BORROW=false means we never borrow from input anyway,
102        // this is safe. We also transmute the HeapValue back to 'static before materializing.
103        #[allow(unsafe_code)]
104        let wip: Partial<'input, false> = unsafe {
105            core::mem::transmute::<Partial<'static, false>, Partial<'input, false>>(
106                Partial::alloc_owned::<T>().map_err(DeserializeError::reflect)?,
107            )
108        };
109        let partial = self.deserialize_into(wip)?;
110        let heap_value: HeapValue<'input, false> =
111            partial.build().map_err(DeserializeError::reflect)?;
112
113        // SAFETY: HeapValue<'input, false> contains no borrowed data because BORROW=false.
114        // The transmute only changes the phantom lifetime marker.
115        #[allow(unsafe_code)]
116        let heap_value: HeapValue<'static, false> = unsafe {
117            core::mem::transmute::<HeapValue<'input, false>, HeapValue<'static, false>>(heap_value)
118        };
119
120        heap_value
121            .materialize::<T>()
122            .map_err(DeserializeError::reflect)
123    }
124
125    /// Deserialize the next value in the stream into `T` (for backward compatibility).
126    pub fn deserialize_root<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
127    where
128        T: Facet<'static>,
129    {
130        self.deserialize()
131    }
132}
133
134impl<'input, const BORROW: bool, P> FormatDeserializer<'input, BORROW, P>
135where
136    P: FormatParser<'input>,
137{
138    /// Read the next event, returning an error if EOF is reached.
139    #[inline]
140    fn expect_event(
141        &mut self,
142        expected: &'static str,
143    ) -> Result<ParseEvent<'input>, DeserializeError<P::Error>> {
144        let event = self
145            .parser
146            .next_event()
147            .map_err(DeserializeError::Parser)?
148            .ok_or(DeserializeError::UnexpectedEof { expected })?;
149        // Capture the span of the consumed event for error reporting
150        self.last_span = self.parser.current_span();
151        Ok(event)
152    }
153
154    /// Peek at the next event, returning an error if EOF is reached.
155    #[inline]
156    fn expect_peek(
157        &mut self,
158        expected: &'static str,
159    ) -> Result<ParseEvent<'input>, DeserializeError<P::Error>> {
160        self.parser
161            .peek_event()
162            .map_err(DeserializeError::Parser)?
163            .ok_or(DeserializeError::UnexpectedEof { expected })
164    }
165
166    /// Main deserialization entry point - deserialize into a Partial.
167    pub fn deserialize_into(
168        &mut self,
169        mut wip: Partial<'input, BORROW>,
170    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
171        let shape = wip.shape();
172
173        // Check for raw capture type (e.g., RawJson)
174        // Raw capture types are tuple structs with a single Cow<str> field
175        // If capture_raw returns None (e.g., streaming mode), fall through
176        // and try normal deserialization (which will likely fail with a helpful error)
177        if self.parser.raw_capture_shape() == Some(shape)
178            && let Some(raw) = self
179                .parser
180                .capture_raw()
181                .map_err(DeserializeError::Parser)?
182        {
183            // The raw type is a tuple struct like RawJson(Cow<str>)
184            // Access field 0 (the Cow<str>) and set it
185            wip = wip.begin_nth_field(0).map_err(DeserializeError::reflect)?;
186            wip = self.set_string_value(wip, Cow::Borrowed(raw))?;
187            wip = wip.end().map_err(DeserializeError::reflect)?;
188            return Ok(wip);
189        }
190
191        // Check for container-level proxy
192        let (wip_returned, has_proxy) = wip
193            .begin_custom_deserialization_from_shape()
194            .map_err(DeserializeError::reflect)?;
195        wip = wip_returned;
196        if has_proxy {
197            wip = self.deserialize_into(wip)?;
198            return wip.end().map_err(DeserializeError::reflect);
199        }
200
201        // Check for field-level proxy (opaque types with proxy attribute)
202        if wip
203            .parent_field()
204            .and_then(|field| field.proxy_convert_in_fn())
205            .is_some()
206        {
207            wip = wip
208                .begin_custom_deserialization()
209                .map_err(DeserializeError::reflect)?;
210            wip = self.deserialize_into(wip)?;
211            wip = wip.end().map_err(DeserializeError::reflect)?;
212            return Ok(wip);
213        }
214
215        // Check Def first for Option
216        if matches!(&shape.def, Def::Option(_)) {
217            return self.deserialize_option(wip);
218        }
219
220        // Check Def for Result - treat it as a 2-variant enum
221        if matches!(&shape.def, Def::Result(_)) {
222            return self.deserialize_result_as_enum(wip);
223        }
224
225        // Priority 1: Check for builder_shape (immutable collections like Bytes -> BytesMut)
226        if shape.builder_shape.is_some() {
227            wip = wip.begin_inner().map_err(DeserializeError::reflect)?;
228            wip = self.deserialize_into(wip)?;
229            wip = wip.end().map_err(DeserializeError::reflect)?;
230            return Ok(wip);
231        }
232
233        // Priority 2: Check for smart pointers (Box, Arc, Rc)
234        if matches!(&shape.def, Def::Pointer(_)) {
235            return self.deserialize_pointer(wip);
236        }
237
238        // Priority 3: Check for .inner (transparent wrappers like NonZero)
239        // Collections (List/Map/Set/Array) have .inner for variance but shouldn't use this path
240        // Opaque scalars (like ULID) may have .inner for documentation but should NOT be
241        // deserialized as transparent wrappers - they use hint_opaque_scalar instead
242        let is_opaque_scalar =
243            matches!(shape.def, Def::Scalar) && matches!(shape.ty, Type::User(UserType::Opaque));
244        if shape.inner.is_some()
245            && !is_opaque_scalar
246            && !matches!(
247                &shape.def,
248                Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
249            )
250        {
251            wip = wip.begin_inner().map_err(DeserializeError::reflect)?;
252            wip = self.deserialize_into(wip)?;
253            wip = wip.end().map_err(DeserializeError::reflect)?;
254            return Ok(wip);
255        }
256
257        // Priority 4: Check for metadata-annotated types (like Spanned<T>)
258        if is_spanned_shape(shape) {
259            return self.deserialize_spanned(wip);
260        }
261
262        // Priority 5: Check the Type for structs and enums
263        match &shape.ty {
264            Type::User(UserType::Struct(struct_def)) => {
265                if matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct) {
266                    return self.deserialize_tuple(wip);
267                }
268                return self.deserialize_struct(wip);
269            }
270            Type::User(UserType::Enum(_)) => return self.deserialize_enum(wip),
271            _ => {}
272        }
273
274        // Priority 6: Check Def for containers and scalars
275        match &shape.def {
276            Def::Scalar => self.deserialize_scalar(wip),
277            Def::List(_) => self.deserialize_list(wip),
278            Def::Map(_) => self.deserialize_map(wip),
279            Def::Array(_) => self.deserialize_array(wip),
280            Def::Set(_) => self.deserialize_set(wip),
281            Def::DynamicValue(_) => self.deserialize_dynamic_value(wip),
282            _ => Err(DeserializeError::Unsupported(format!(
283                "unsupported shape def: {:?}",
284                shape.def
285            ))),
286        }
287    }
288
289    fn deserialize_option(
290        &mut self,
291        mut wip: Partial<'input, BORROW>,
292    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
293        // Hint to non-self-describing parsers that an Option is expected
294        self.parser.hint_option();
295
296        let event = self.expect_peek("value for option")?;
297
298        if matches!(event, ParseEvent::Scalar(ScalarValue::Null)) {
299            // Consume the null
300            let _ = self.expect_event("null")?;
301            // Set to None (default)
302            wip = wip.set_default().map_err(DeserializeError::reflect)?;
303        } else {
304            // Some(value)
305            wip = wip.begin_some().map_err(DeserializeError::reflect)?;
306            wip = self.deserialize_into(wip)?;
307            wip = wip.end().map_err(DeserializeError::reflect)?;
308        }
309        Ok(wip)
310    }
311
312    fn deserialize_result_as_enum(
313        &mut self,
314        mut wip: Partial<'input, BORROW>,
315    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
316        use facet_core::StructKind;
317
318        // Hint to non-self-describing parsers that a Result enum is expected
319        // Result is encoded as a 2-variant enum: Ok (index 0) and Err (index 1)
320        let variant_hints: Vec<crate::EnumVariantHint> = vec![
321            crate::EnumVariantHint {
322                name: "Ok",
323                kind: StructKind::TupleStruct,
324                field_count: 1,
325            },
326            crate::EnumVariantHint {
327                name: "Err",
328                kind: StructKind::TupleStruct,
329                field_count: 1,
330            },
331        ];
332        self.parser.hint_enum(&variant_hints);
333
334        // Read the StructStart emitted by the parser after hint_enum
335        let event = self.expect_event("struct start for Result")?;
336        if !matches!(event, ParseEvent::StructStart(_)) {
337            return Err(DeserializeError::TypeMismatch {
338                expected: "struct start for Result variant",
339                got: format!("{event:?}"),
340            });
341        }
342
343        // Read the FieldKey with the variant name ("Ok" or "Err")
344        let key_event = self.expect_event("variant key for Result")?;
345        let variant_name = match key_event {
346            ParseEvent::FieldKey(key) => key.name,
347            other => {
348                return Err(DeserializeError::TypeMismatch {
349                    expected: "field key with variant name",
350                    got: format!("{other:?}"),
351                });
352            }
353        };
354
355        // Select the appropriate variant and deserialize its content
356        if variant_name == "Ok" {
357            wip = wip.begin_ok().map_err(DeserializeError::reflect)?;
358        } else if variant_name == "Err" {
359            wip = wip.begin_err().map_err(DeserializeError::reflect)?;
360        } else {
361            return Err(DeserializeError::TypeMismatch {
362                expected: "Ok or Err variant",
363                got: alloc::format!("variant '{}'", variant_name),
364            });
365        }
366
367        // Deserialize the variant's value (newtype pattern - single field)
368        wip = self.deserialize_into(wip)?;
369        wip = wip.end().map_err(DeserializeError::reflect)?;
370
371        // Consume StructEnd
372        let end_event = self.expect_event("struct end for Result")?;
373        if !matches!(end_event, ParseEvent::StructEnd) {
374            return Err(DeserializeError::TypeMismatch {
375                expected: "struct end for Result variant",
376                got: format!("{end_event:?}"),
377            });
378        }
379
380        Ok(wip)
381    }
382
383    fn deserialize_pointer(
384        &mut self,
385        mut wip: Partial<'input, BORROW>,
386    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
387        use facet_core::KnownPointer;
388
389        let shape = wip.shape();
390        let is_cow = if let Def::Pointer(ptr_def) = shape.def {
391            matches!(ptr_def.known, Some(KnownPointer::Cow))
392        } else {
393            false
394        };
395
396        if is_cow {
397            // Cow<str> - handle specially to preserve borrowing
398            if let Def::Pointer(ptr_def) = shape.def
399                && let Some(pointee) = ptr_def.pointee()
400                && pointee.type_identifier == "str"
401            {
402                // Hint to non-self-describing parsers that a string is expected
403                self.parser.hint_scalar_type(ScalarTypeHint::String);
404                let event = self.expect_event("string for Cow<str>")?;
405                if let ParseEvent::Scalar(ScalarValue::Str(s)) = event {
406                    // Pass through the Cow as-is to preserve borrowing
407                    wip = wip.set(s).map_err(DeserializeError::reflect)?;
408                    return Ok(wip);
409                } else {
410                    return Err(DeserializeError::TypeMismatch {
411                        expected: "string for Cow<str>",
412                        got: format!("{event:?}"),
413                    });
414                }
415            }
416            // Cow<[u8]> - handle specially to preserve borrowing
417            if let Def::Pointer(ptr_def) = shape.def
418                && let Some(pointee) = ptr_def.pointee()
419                && let Def::Slice(slice_def) = pointee.def
420                && slice_def.t.type_identifier == "u8"
421            {
422                // Hint to non-self-describing parsers that bytes are expected
423                self.parser.hint_scalar_type(ScalarTypeHint::Bytes);
424                let event = self.expect_event("bytes for Cow<[u8]>")?;
425                if let ParseEvent::Scalar(ScalarValue::Bytes(b)) = event {
426                    // Pass through the Cow as-is to preserve borrowing
427                    wip = wip.set(b).map_err(DeserializeError::reflect)?;
428                    return Ok(wip);
429                } else {
430                    return Err(DeserializeError::TypeMismatch {
431                        expected: "bytes for Cow<[u8]>",
432                        got: format!("{event:?}"),
433                    });
434                }
435            }
436            // Other Cow types - use begin_inner
437            wip = wip.begin_inner().map_err(DeserializeError::reflect)?;
438            wip = self.deserialize_into(wip)?;
439            wip = wip.end().map_err(DeserializeError::reflect)?;
440            return Ok(wip);
441        }
442
443        // &str - handle specially for zero-copy borrowing
444        if let Def::Pointer(ptr_def) = shape.def
445            && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
446            && ptr_def
447                .pointee()
448                .is_some_and(|p| p.type_identifier == "str")
449        {
450            // Hint to non-self-describing parsers that a string is expected
451            self.parser.hint_scalar_type(ScalarTypeHint::String);
452            let event = self.expect_event("string for &str")?;
453            if let ParseEvent::Scalar(ScalarValue::Str(s)) = event {
454                return self.set_string_value(wip, s);
455            } else {
456                return Err(DeserializeError::TypeMismatch {
457                    expected: "string for &str",
458                    got: format!("{event:?}"),
459                });
460            }
461        }
462
463        // &[u8] - handle specially for zero-copy borrowing
464        if let Def::Pointer(ptr_def) = shape.def
465            && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
466            && let Some(pointee) = ptr_def.pointee()
467            && let Def::Slice(slice_def) = pointee.def
468            && slice_def.t.type_identifier == "u8"
469        {
470            // Hint to non-self-describing parsers that bytes are expected
471            self.parser.hint_scalar_type(ScalarTypeHint::Bytes);
472            let event = self.expect_event("bytes for &[u8]")?;
473            if let ParseEvent::Scalar(ScalarValue::Bytes(b)) = event {
474                return self.set_bytes_value(wip, b);
475            } else {
476                return Err(DeserializeError::TypeMismatch {
477                    expected: "bytes for &[u8]",
478                    got: format!("{event:?}"),
479                });
480            }
481        }
482
483        // Regular smart pointer (Box, Arc, Rc)
484        wip = wip.begin_smart_ptr().map_err(DeserializeError::reflect)?;
485
486        // Check if begin_smart_ptr set up a slice builder (for Arc<[T]>, Rc<[T]>, Box<[T]>)
487        // In this case, we need to deserialize as a list manually
488        let is_slice_builder = wip.is_building_smart_ptr_slice();
489
490        if is_slice_builder {
491            // Deserialize the list elements into the slice builder
492            // We can't use deserialize_list() because it calls begin_list() which interferes
493            // Hint to non-self-describing parsers that a sequence is expected
494            self.parser.hint_sequence();
495            let event = self.expect_event("value")?;
496
497            // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
498            // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
499            let struct_mode = match event {
500                ParseEvent::SequenceStart(_) => false,
501                ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
502                ParseEvent::StructStart(kind) => {
503                    return Err(DeserializeError::TypeMismatch {
504                        expected: "array",
505                        got: kind.name().into(),
506                    });
507                }
508                _ => {
509                    return Err(DeserializeError::TypeMismatch {
510                        expected: "sequence start for Arc<[T]>/Rc<[T]>/Box<[T]>",
511                        got: format!("{event:?}"),
512                    });
513                }
514            };
515
516            loop {
517                let event = self.expect_peek("value")?;
518
519                // Check for end of container
520                if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
521                    self.expect_event("value")?;
522                    break;
523                }
524
525                // In struct mode, skip FieldKey events
526                if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
527                    self.expect_event("value")?;
528                    continue;
529                }
530
531                wip = wip.begin_list_item().map_err(DeserializeError::reflect)?;
532                wip = self.deserialize_into(wip)?;
533                wip = wip.end().map_err(DeserializeError::reflect)?;
534            }
535
536            // Convert the slice builder to Arc/Rc/Box and mark as initialized
537            wip = wip.end().map_err(DeserializeError::reflect)?;
538            // DON'T call end() again - the caller (deserialize_struct) will do that
539        } else {
540            // Regular smart pointer with sized pointee
541            wip = self.deserialize_into(wip)?;
542            wip = wip.end().map_err(DeserializeError::reflect)?;
543        }
544
545        Ok(wip)
546    }
547
548    /// Check if a field matches the given name, namespace, and location constraints.
549    ///
550    /// This implements format-specific field matching for XML and KDL:
551    ///
552    /// **XML matching:**
553    /// - Text: Match fields with xml::text attribute (name is ignored - text content goes to the field)
554    /// - Attributes: Only match if explicit xml::ns matches (no ns_all inheritance per XML spec)
555    /// - Elements: Match if explicit xml::ns OR ns_all matches
556    ///
557    /// **KDL matching:**
558    /// - Argument: Match fields with kdl::argument attribute
559    /// - Property: Match fields with kdl::property attribute
560    /// - Child: Match fields with kdl::child or kdl::children attribute
561    ///
562    /// **Default (KeyValue):** Match by name/alias only (backwards compatible)
563    ///
564    /// TODO: This function hardcodes knowledge of XML and KDL attributes.
565    /// See <https://github.com/facet-rs/facet/issues/1506> for discussion on
566    /// making this more extensible.
567    fn field_matches_with_namespace(
568        field: &facet_core::Field,
569        name: &str,
570        namespace: Option<&str>,
571        location: FieldLocationHint,
572        ns_all: Option<&str>,
573    ) -> bool {
574        // === XML/HTML: Text location matches fields with text attribute ===
575        // The name "_text" from the parser is ignored - we match by attribute presence
576        if matches!(location, FieldLocationHint::Text) {
577            return field.is_text();
578        }
579
580        // === KDL: Argument location matches fields with kdl::argument attribute ===
581        // For kdl::argument, we match by attribute presence, not by name
582        // (arguments are positional, name in FieldKey is just "_arg" or index)
583        // If no kdl::argument attr, fall through to name matching
584        if matches!(location, FieldLocationHint::Argument) && field.is_argument() {
585            return true;
586        }
587
588        // === KDL: Property location matches fields with kdl::property attribute ===
589        // For properties, we need BOTH the attribute AND name match
590        // If no kdl::property attr, fall through to name matching
591        if matches!(location, FieldLocationHint::Property) && field.is_property() {
592            let name_matches = field.name == name || field.alias.iter().any(|alias| *alias == name);
593            return name_matches;
594        }
595
596        // === Check name/alias ===
597        let name_matches = field.name == name || field.alias.iter().any(|alias| *alias == name);
598
599        if !name_matches {
600            return false;
601        }
602
603        // === KDL/XML/HTML: Child location matches fields with child/element attributes ===
604        if matches!(location, FieldLocationHint::Child) {
605            // If field has explicit child/element attribute, it can match Child location
606            // If field has NO child attribute, it can still match by name (backwards compat)
607            if field.is_element() || field.is_elements() {
608                // Has explicit child marker - allow match
609                // (name already matched above)
610            }
611            // Fall through to namespace check for XML
612        }
613
614        // === XML: Namespace matching ===
615        // Get the expected namespace for this field
616        let field_xml_ns = field
617            .get_attr(Some("xml"), "ns")
618            .and_then(|attr| attr.get_as::<&str>().copied());
619
620        // CRITICAL: Attributes don't inherit ns_all (per XML spec)
621        let expected_ns = if matches!(location, FieldLocationHint::Attribute) {
622            field_xml_ns // Attributes: only explicit xml::ns
623        } else {
624            field_xml_ns.or(ns_all) // Elements: xml::ns OR ns_all
625        };
626
627        // Check if namespaces match
628        match (namespace, expected_ns) {
629            (Some(input_ns), Some(expected)) => input_ns == expected,
630            (Some(_input_ns), None) => true, // Input has namespace, field doesn't require one - match
631            (None, Some(_expected)) => false, // Input has no namespace, field requires one - NO match
632            (None, None) => true,             // Neither has namespace - match
633        }
634    }
635
636    fn deserialize_struct(
637        &mut self,
638        wip: Partial<'input, BORROW>,
639    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
640        // Get struct fields for lookup
641        let struct_def = match &wip.shape().ty {
642            Type::User(UserType::Struct(def)) => def,
643            _ => {
644                return Err(DeserializeError::Unsupported(format!(
645                    "expected struct type but got {:?}",
646                    wip.shape().ty
647                )));
648            }
649        };
650
651        // Check if we have any flattened fields
652        let has_flatten = struct_def.fields.iter().any(|f| f.is_flattened());
653
654        if has_flatten {
655            // Check if any flatten field is an enum (requires solver)
656            // or if there's nested flatten (flatten inside flatten) that isn't just a map
657            let needs_solver = struct_def.fields.iter().any(|f| {
658                if !f.is_flattened() {
659                    return false;
660                }
661                // Get inner type, unwrapping Option if present
662                let inner_shape = match f.shape().def {
663                    Def::Option(opt) => opt.t,
664                    _ => f.shape(),
665                };
666                match inner_shape.ty {
667                    // Enum flatten needs solver
668                    Type::User(UserType::Enum(_)) => true,
669                    // Check for nested flatten (flatten field has its own flatten fields)
670                    // Exclude flattened maps as they just catch unknown keys, not nested fields
671                    Type::User(UserType::Struct(inner_struct)) => {
672                        inner_struct.fields.iter().any(|inner_f| {
673                            inner_f.is_flattened() && {
674                                let inner_inner_shape = match inner_f.shape().def {
675                                    Def::Option(opt) => opt.t,
676                                    _ => inner_f.shape(),
677                                };
678                                // Maps don't create nested field structures
679                                !matches!(inner_inner_shape.def, Def::Map(_))
680                            }
681                        })
682                    }
683                    _ => false,
684                }
685            });
686
687            if needs_solver {
688                self.deserialize_struct_with_flatten(wip)
689            } else {
690                // Simple single-level flatten - use the original approach
691                self.deserialize_struct_single_flatten(wip)
692            }
693        } else {
694            self.deserialize_struct_simple(wip)
695        }
696    }
697
698    /// Deserialize a struct without flattened fields (simple case).
699    fn deserialize_struct_simple(
700        &mut self,
701        mut wip: Partial<'input, BORROW>,
702    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
703        use facet_core::Characteristic;
704
705        // Get struct fields for lookup (needed before hint)
706        let struct_def = match &wip.shape().ty {
707            Type::User(UserType::Struct(def)) => def,
708            _ => {
709                return Err(DeserializeError::Unsupported(format!(
710                    "expected struct type but got {:?}",
711                    wip.shape().ty
712                )));
713            }
714        };
715
716        // Hint to non-self-describing parsers how many fields to expect
717        self.parser.hint_struct_fields(struct_def.fields.len());
718
719        let struct_has_default = wip.shape().has_default_attr();
720
721        // Expect StructStart, but for XML/HTML, a scalar means text-only element
722        let event = self.expect_event("value")?;
723        if let ParseEvent::Scalar(scalar) = &event {
724            // For XML/HTML, a text-only element is emitted as a scalar.
725            // If the struct has a text field, set it from the scalar.
726            if let Some((idx, _field)) = struct_def
727                .fields
728                .iter()
729                .enumerate()
730                .find(|(_, f)| f.is_text())
731            {
732                wip = wip
733                    .begin_nth_field(idx)
734                    .map_err(DeserializeError::reflect)?;
735
736                // Handle Option<T>
737                let is_option = matches!(&wip.shape().def, Def::Option(_));
738                if is_option {
739                    wip = wip.begin_some().map_err(DeserializeError::reflect)?;
740                }
741
742                wip = self.set_scalar(wip, scalar.clone())?;
743
744                if is_option {
745                    wip = wip.end().map_err(DeserializeError::reflect)?;
746                }
747                wip = wip.end().map_err(DeserializeError::reflect)?;
748
749                // Set defaults for other fields
750                for (other_idx, other_field) in struct_def.fields.iter().enumerate() {
751                    if other_idx == idx {
752                        continue;
753                    }
754
755                    let field_has_default = other_field.has_default();
756                    let field_type_has_default =
757                        other_field.shape().is(facet_core::Characteristic::Default);
758                    let field_is_option = matches!(other_field.shape().def, Def::Option(_));
759
760                    if field_has_default || (struct_has_default && field_type_has_default) {
761                        wip = wip
762                            .set_nth_field_to_default(other_idx)
763                            .map_err(DeserializeError::reflect)?;
764                    } else if field_is_option {
765                        wip = wip
766                            .begin_field(other_field.name)
767                            .map_err(DeserializeError::reflect)?;
768                        wip = wip.set_default().map_err(DeserializeError::reflect)?;
769                        wip = wip.end().map_err(DeserializeError::reflect)?;
770                    } else if other_field.should_skip_deserializing() {
771                        wip = wip
772                            .set_nth_field_to_default(other_idx)
773                            .map_err(DeserializeError::reflect)?;
774                    }
775                    // If a field is required and not set, that's an error, but we'll
776                    // leave that for the struct-level validation
777                }
778
779                return Ok(wip);
780            }
781
782            // No xml::text field - this is an error
783            return Err(DeserializeError::TypeMismatch {
784                expected: "struct start",
785                got: format!("{event:?}"),
786            });
787        }
788
789        if !matches!(event, ParseEvent::StructStart(_)) {
790            return Err(DeserializeError::TypeMismatch {
791                expected: "struct start",
792                got: format!("{event:?}"),
793            });
794        }
795        let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
796
797        // Extract container-level default namespace (xml::ns_all) for namespace-aware matching
798        let ns_all = wip
799            .shape()
800            .attributes
801            .iter()
802            .find(|attr| attr.ns == Some("xml") && attr.key == "ns_all")
803            .and_then(|attr| attr.get_as::<&str>().copied());
804
805        // Track which fields have been set
806        let num_fields = struct_def.fields.len();
807        let mut fields_set = alloc::vec![false; num_fields];
808        let mut ordered_field_index = 0usize;
809
810        // Track xml::elements field state for collecting child elements into lists
811        // When Some((idx, in_list)), we're collecting items into field at idx
812        let mut elements_field_state: Option<(usize, bool)> = None;
813
814        loop {
815            let event = self.expect_event("value")?;
816            match event {
817                ParseEvent::StructEnd => {
818                    // End any open xml::elements field
819                    // Note: begin_list() doesn't push a frame, so we only need to end the field
820                    if let Some((_, true)) = elements_field_state {
821                        wip = wip.end().map_err(DeserializeError::reflect)?; // end field only
822                    }
823                    break;
824                }
825                ParseEvent::OrderedField => {
826                    // Non-self-describing formats emit OrderedField events in order
827                    let idx = ordered_field_index;
828                    ordered_field_index += 1;
829                    if idx < num_fields {
830                        wip = wip
831                            .begin_nth_field(idx)
832                            .map_err(DeserializeError::reflect)?;
833                        wip = self.deserialize_into(wip)?;
834                        wip = wip.end().map_err(DeserializeError::reflect)?;
835                        fields_set[idx] = true;
836                    }
837                }
838                ParseEvent::FieldKey(key) => {
839                    // Look up field in struct fields (direct match)
840                    // Exclude xml::elements fields - they accumulate repeated child elements
841                    // and must be handled via find_elements_field_for_element below
842                    let field_info = struct_def.fields.iter().enumerate().find(|(_, f)| {
843                        !f.is_elements()
844                            && Self::field_matches_with_namespace(
845                                f,
846                                key.name.as_ref(),
847                                key.namespace.as_deref(),
848                                key.location,
849                                ns_all,
850                            )
851                    });
852
853                    if let Some((idx, _field)) = field_info {
854                        // End any open xml::elements field before switching to a different field
855                        // Note: begin_list() doesn't push a frame, so we only end the field
856                        if let Some((elem_idx, true)) = elements_field_state
857                            && elem_idx != idx
858                        {
859                            wip = wip.end().map_err(DeserializeError::reflect)?; // end field only
860                            elements_field_state = None;
861                        }
862
863                        wip = wip
864                            .begin_nth_field(idx)
865                            .map_err(DeserializeError::reflect)?;
866                        wip = self.deserialize_into(wip)?;
867                        wip = wip.end().map_err(DeserializeError::reflect)?;
868                        fields_set[idx] = true;
869                        continue;
870                    }
871
872                    // Check if this child element should go into an elements field
873                    if key.location == FieldLocationHint::Child
874                        && let Some((idx, field)) = self.find_elements_field_for_element(
875                            struct_def.fields,
876                            key.name.as_ref(),
877                            key.namespace.as_deref(),
878                            ns_all,
879                        )
880                    {
881                        // Start or continue the list for this elements field
882                        match elements_field_state {
883                            None => {
884                                // Start new list
885                                wip = wip
886                                    .begin_nth_field(idx)
887                                    .map_err(DeserializeError::reflect)?;
888                                wip = wip.begin_list().map_err(DeserializeError::reflect)?;
889                                elements_field_state = Some((idx, true));
890                                fields_set[idx] = true;
891                            }
892                            Some((current_idx, true)) if current_idx != idx => {
893                                // Switching to a different xml::elements field
894                                // Note: begin_list() doesn't push a frame, so we only end the field
895                                wip = wip.end().map_err(DeserializeError::reflect)?; // end field only
896                                wip = wip
897                                    .begin_nth_field(idx)
898                                    .map_err(DeserializeError::reflect)?;
899                                wip = wip.begin_list().map_err(DeserializeError::reflect)?;
900                                elements_field_state = Some((idx, true));
901                                fields_set[idx] = true;
902                            }
903                            Some((current_idx, true)) if current_idx == idx => {
904                                // Continue adding to same list
905                            }
906                            _ => {}
907                        }
908
909                        // Add item to list
910                        wip = wip.begin_list_item().map_err(DeserializeError::reflect)?;
911
912                        // For enum item types, we need to select the variant based on element name
913                        let item_shape = Self::get_list_item_shape(field.shape());
914                        if let Some(item_shape) = item_shape {
915                            if let Type::User(UserType::Enum(enum_def)) = &item_shape.ty {
916                                // Find matching variant
917                                if let Some(variant_idx) =
918                                    Self::find_variant_for_element(enum_def, key.name.as_ref())
919                                {
920                                    wip = wip
921                                        .select_nth_variant(variant_idx)
922                                        .map_err(DeserializeError::reflect)?;
923                                    // After selecting variant, deserialize the variant content
924                                    wip = self.deserialize_enum_variant_content(wip)?;
925                                } else {
926                                    // No matching variant - deserialize directly
927                                    wip = self.deserialize_into(wip)?;
928                                }
929                            } else {
930                                // Not an enum - deserialize directly
931                                wip = self.deserialize_into(wip)?;
932                            }
933                        } else {
934                            wip = self.deserialize_into(wip)?;
935                        }
936
937                        wip = wip.end().map_err(DeserializeError::reflect)?; // end list item
938                        continue;
939                    }
940
941                    if deny_unknown_fields {
942                        return Err(DeserializeError::UnknownField(key.name.into_owned()));
943                    } else {
944                        // Unknown field - skip it
945                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
946                    }
947                }
948                other => {
949                    return Err(DeserializeError::TypeMismatch {
950                        expected: "field key or struct end",
951                        got: format!("{other:?}"),
952                    });
953                }
954            }
955        }
956
957        // Apply defaults for missing fields
958        // First, check if ALL non-elements fields are missing and the struct has a container-level
959        // default. In that case, use the struct's Default impl directly.
960        let all_non_elements_missing = struct_def
961            .fields
962            .iter()
963            .enumerate()
964            .all(|(idx, field)| !fields_set[idx] || field.is_elements());
965
966        if struct_has_default && all_non_elements_missing && wip.shape().is(Characteristic::Default)
967        {
968            // Use the struct's Default impl for all fields at once
969            wip = wip.set_default().map_err(DeserializeError::reflect)?;
970            return Ok(wip);
971        }
972
973        for (idx, field) in struct_def.fields.iter().enumerate() {
974            if fields_set[idx] {
975                continue;
976            }
977
978            let field_has_default = field.has_default();
979            let field_type_has_default = field.shape().is(Characteristic::Default);
980            let field_is_option = matches!(field.shape().def, Def::Option(_));
981
982            // elements fields with no items should get an empty list
983            // begin_list() doesn't push a frame, so we just begin the field, begin the list,
984            // then end the field (no end() for the list itself).
985            if field.is_elements() {
986                wip = wip
987                    .begin_nth_field(idx)
988                    .map_err(DeserializeError::reflect)?;
989                wip = wip.begin_list().map_err(DeserializeError::reflect)?;
990                wip = wip.end().map_err(DeserializeError::reflect)?; // end field only
991                continue;
992            }
993
994            if field_has_default || (struct_has_default && field_type_has_default) {
995                wip = wip
996                    .set_nth_field_to_default(idx)
997                    .map_err(DeserializeError::reflect)?;
998            } else if field_is_option {
999                wip = wip
1000                    .begin_field(field.name)
1001                    .map_err(DeserializeError::reflect)?;
1002                wip = wip.set_default().map_err(DeserializeError::reflect)?;
1003                wip = wip.end().map_err(DeserializeError::reflect)?;
1004            } else if field.should_skip_deserializing() {
1005                wip = wip
1006                    .set_nth_field_to_default(idx)
1007                    .map_err(DeserializeError::reflect)?;
1008            } else {
1009                return Err(DeserializeError::TypeMismatch {
1010                    expected: "field to be present or have default",
1011                    got: format!("missing field '{}'", field.name),
1012                });
1013            }
1014        }
1015
1016        Ok(wip)
1017    }
1018
1019    /// Find an elements field that can accept a child element with the given name.
1020    fn find_elements_field_for_element<'a>(
1021        &self,
1022        fields: &'a [facet_core::Field],
1023        element_name: &str,
1024        element_ns: Option<&str>,
1025        ns_all: Option<&str>,
1026    ) -> Option<(usize, &'a facet_core::Field)> {
1027        for (idx, field) in fields.iter().enumerate() {
1028            if !field.is_elements() {
1029                continue;
1030            }
1031
1032            // Get the list item shape
1033            let item_shape = Self::get_list_item_shape(field.shape())?;
1034
1035            // Check if the item type can accept this element
1036            if Self::shape_accepts_element(item_shape, element_name, element_ns, ns_all) {
1037                return Some((idx, field));
1038            }
1039
1040            // Also check singularization: if element_name is the singular of field.name
1041            // This handles cases like: field `items: Vec<Item>` with `#[facet(kdl::children)]`
1042            // accepting child nodes named "item"
1043            if facet_singularize::is_singular_of(element_name, field.name) {
1044                return Some((idx, field));
1045            }
1046        }
1047        None
1048    }
1049
1050    /// Get the item shape from a list-like field shape.
1051    fn get_list_item_shape(shape: &facet_core::Shape) -> Option<&'static facet_core::Shape> {
1052        match &shape.def {
1053            Def::List(list_def) => Some(list_def.t()),
1054            _ => None,
1055        }
1056    }
1057
1058    /// Check if a shape can accept an element with the given name.
1059    fn shape_accepts_element(
1060        shape: &facet_core::Shape,
1061        element_name: &str,
1062        _element_ns: Option<&str>,
1063        _ns_all: Option<&str>,
1064    ) -> bool {
1065        match &shape.ty {
1066            Type::User(UserType::Enum(enum_def)) => {
1067                // For enums, check if element name matches any variant
1068                enum_def.variants.iter().any(|v| {
1069                    let display_name = Self::get_variant_display_name(v);
1070                    display_name == element_name
1071                })
1072            }
1073            Type::User(UserType::Struct(_)) => {
1074                // For structs, check if element name matches struct's name
1075                let display_name = Self::get_shape_display_name(shape);
1076                display_name == element_name
1077            }
1078            _ => {
1079                // For other types, use type identifier
1080                shape.type_identifier == element_name
1081            }
1082        }
1083    }
1084
1085    /// Get the display name for a variant (respecting rename attribute).
1086    fn get_variant_display_name(variant: &facet_core::Variant) -> &'static str {
1087        if let Some(attr) = variant.get_builtin_attr("rename")
1088            && let Some(&renamed) = attr.get_as::<&str>()
1089        {
1090            return renamed;
1091        }
1092        variant.name
1093    }
1094
1095    /// Get the display name for a shape (respecting rename attribute).
1096    fn get_shape_display_name(shape: &facet_core::Shape) -> &'static str {
1097        if let Some(renamed) = shape.get_builtin_attr_value::<&str>("rename") {
1098            return renamed;
1099        }
1100        shape.type_identifier
1101    }
1102
1103    /// Find the variant index for an enum that matches the given element name.
1104    fn find_variant_for_element(
1105        enum_def: &facet_core::EnumType,
1106        element_name: &str,
1107    ) -> Option<usize> {
1108        enum_def.variants.iter().position(|v| {
1109            let display_name = Self::get_variant_display_name(v);
1110            display_name == element_name
1111        })
1112    }
1113
1114    /// Deserialize a struct with single-level flattened fields (original approach).
1115    /// This handles simple flatten cases where there's no nested flatten or enum flatten.
1116    fn deserialize_struct_single_flatten(
1117        &mut self,
1118        mut wip: Partial<'input, BORROW>,
1119    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1120        use alloc::collections::BTreeMap;
1121        use facet_core::Characteristic;
1122        use facet_reflect::Resolution;
1123
1124        // Get struct fields for lookup
1125        let struct_def = match &wip.shape().ty {
1126            Type::User(UserType::Struct(def)) => def,
1127            _ => {
1128                return Err(DeserializeError::Unsupported(format!(
1129                    "expected struct type but got {:?}",
1130                    wip.shape().ty
1131                )));
1132            }
1133        };
1134
1135        let struct_has_default = wip.shape().has_default_attr();
1136
1137        // Expect StructStart, but for XML/HTML, a scalar means text-only element
1138        let event = self.expect_event("value")?;
1139        if let ParseEvent::Scalar(scalar) = &event {
1140            // For XML/HTML, a text-only element is emitted as a scalar.
1141            // If the struct has a text field, set it from the scalar and default the rest.
1142            if let Some((idx, _field)) = struct_def
1143                .fields
1144                .iter()
1145                .enumerate()
1146                .find(|(_, f)| f.is_text())
1147            {
1148                wip = wip
1149                    .begin_nth_field(idx)
1150                    .map_err(DeserializeError::reflect)?;
1151
1152                // Handle Option<T>
1153                let is_option = matches!(&wip.shape().def, Def::Option(_));
1154                if is_option {
1155                    wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1156                }
1157
1158                wip = self.set_scalar(wip, scalar.clone())?;
1159
1160                if is_option {
1161                    wip = wip.end().map_err(DeserializeError::reflect)?;
1162                }
1163                wip = wip.end().map_err(DeserializeError::reflect)?;
1164
1165                // Set defaults for other fields (including flattened ones)
1166                for (other_idx, other_field) in struct_def.fields.iter().enumerate() {
1167                    if other_idx == idx {
1168                        continue;
1169                    }
1170
1171                    let field_has_default = other_field.has_default();
1172                    let field_type_has_default =
1173                        other_field.shape().is(facet_core::Characteristic::Default);
1174                    let field_is_option = matches!(other_field.shape().def, Def::Option(_));
1175
1176                    if field_has_default || (struct_has_default && field_type_has_default) {
1177                        wip = wip
1178                            .set_nth_field_to_default(other_idx)
1179                            .map_err(DeserializeError::reflect)?;
1180                    } else if field_is_option {
1181                        wip = wip
1182                            .begin_field(other_field.name)
1183                            .map_err(DeserializeError::reflect)?;
1184                        wip = wip.set_default().map_err(DeserializeError::reflect)?;
1185                        wip = wip.end().map_err(DeserializeError::reflect)?;
1186                    } else if other_field.should_skip_deserializing() {
1187                        // Skip fields that are marked for skip deserializing
1188                        continue;
1189                    } else {
1190                        return Err(DeserializeError::TypeMismatch {
1191                            expected: "field to be present or have default",
1192                            got: format!("missing field '{}'", other_field.name),
1193                        });
1194                    }
1195                }
1196
1197                return Ok(wip);
1198            }
1199        }
1200
1201        if !matches!(event, ParseEvent::StructStart(_)) {
1202            return Err(DeserializeError::TypeMismatch {
1203                expected: "struct start",
1204                got: format!("{event:?}"),
1205            });
1206        }
1207        let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
1208
1209        // Extract container-level default namespace (xml::ns_all) for namespace-aware matching
1210        let ns_all = wip
1211            .shape()
1212            .attributes
1213            .iter()
1214            .find(|attr| attr.ns == Some("xml") && attr.key == "ns_all")
1215            .and_then(|attr| attr.get_as::<&str>().copied());
1216
1217        // Track which fields have been set
1218        let num_fields = struct_def.fields.len();
1219        let mut fields_set = alloc::vec![false; num_fields];
1220
1221        // Build flatten info: for each flattened field, get its inner struct fields
1222        // and track which inner fields have been set
1223        let mut flatten_info: alloc::vec::Vec<
1224            Option<(&'static [facet_core::Field], alloc::vec::Vec<bool>)>,
1225        > = alloc::vec![None; num_fields];
1226
1227        // Track which fields are DynamicValue flattens (like facet_value::Value)
1228        let mut dynamic_value_flattens: alloc::vec::Vec<bool> = alloc::vec![false; num_fields];
1229
1230        // Track flattened map field index (for collecting unknown keys)
1231        let mut flatten_map_idx: Option<usize> = None;
1232
1233        // Track field names across flattened structs to detect duplicates
1234        let mut flatten_field_names: BTreeMap<&str, usize> = BTreeMap::new();
1235
1236        for (idx, field) in struct_def.fields.iter().enumerate() {
1237            if field.is_flattened() {
1238                // Handle Option<T> flatten by unwrapping to inner type
1239                let inner_shape = match field.shape().def {
1240                    Def::Option(opt) => opt.t,
1241                    _ => field.shape(),
1242                };
1243
1244                // Check if this is a DynamicValue flatten (like facet_value::Value)
1245                if matches!(inner_shape.def, Def::DynamicValue(_)) {
1246                    dynamic_value_flattens[idx] = true;
1247                } else if matches!(inner_shape.def, Def::Map(_)) {
1248                    // Flattened map - collects unknown keys
1249                    flatten_map_idx = Some(idx);
1250                } else if let Type::User(UserType::Struct(inner_def)) = &inner_shape.ty {
1251                    let inner_fields = inner_def.fields;
1252                    let inner_set = alloc::vec![false; inner_fields.len()];
1253                    flatten_info[idx] = Some((inner_fields, inner_set));
1254
1255                    // Check for duplicate field names across flattened structs
1256                    for inner_field in inner_fields.iter() {
1257                        let field_name = inner_field.rename.unwrap_or(inner_field.name);
1258                        if let Some(_prev_idx) = flatten_field_names.insert(field_name, idx) {
1259                            return Err(DeserializeError::Unsupported(format!(
1260                                "duplicate field `{}` in flattened structs",
1261                                field_name
1262                            )));
1263                        }
1264                    }
1265                }
1266            }
1267        }
1268
1269        // Enter deferred mode for flatten handling (if not already in deferred mode)
1270        let already_deferred = wip.is_deferred();
1271        if !already_deferred {
1272            let resolution = Resolution::new();
1273            wip = wip
1274                .begin_deferred(resolution)
1275                .map_err(DeserializeError::reflect)?;
1276        }
1277
1278        // Track xml::elements field state for collecting child elements into lists
1279        // (field_idx, is_open)
1280        let mut elements_field_state: Option<(usize, bool)> = None;
1281
1282        loop {
1283            let event = self.expect_event("value")?;
1284            match event {
1285                ParseEvent::StructEnd => {
1286                    // End any open xml::elements field
1287                    if let Some((_, true)) = elements_field_state {
1288                        wip = wip.end().map_err(DeserializeError::reflect)?; // end field only
1289                    }
1290                    break;
1291                }
1292                ParseEvent::FieldKey(key) => {
1293                    // First, look up field in direct struct fields (non-flattened, non-elements)
1294                    // Exclude xml::elements fields - they accumulate repeated child elements
1295                    // and must be handled via find_elements_field_for_element below
1296                    let direct_field_info = struct_def.fields.iter().enumerate().find(|(_, f)| {
1297                        !f.is_flattened()
1298                            && !f.is_elements()
1299                            && Self::field_matches_with_namespace(
1300                                f,
1301                                key.name.as_ref(),
1302                                key.namespace.as_deref(),
1303                                key.location,
1304                                ns_all,
1305                            )
1306                    });
1307
1308                    if let Some((idx, _field)) = direct_field_info {
1309                        // End any open xml::elements field before switching to a different field
1310                        if let Some((elem_idx, true)) = elements_field_state
1311                            && elem_idx != idx
1312                        {
1313                            wip = wip.end().map_err(DeserializeError::reflect)?; // end field only
1314                            elements_field_state = None;
1315                        }
1316
1317                        wip = wip
1318                            .begin_nth_field(idx)
1319                            .map_err(DeserializeError::reflect)?;
1320                        wip = self.deserialize_into(wip)?;
1321                        wip = wip.end().map_err(DeserializeError::reflect)?;
1322                        fields_set[idx] = true;
1323                        continue;
1324                    }
1325
1326                    // Check if this child element or text node should go into an xml::elements field
1327                    // This handles both child elements and text nodes in mixed content
1328                    if matches!(
1329                        key.location,
1330                        FieldLocationHint::Child | FieldLocationHint::Text
1331                    ) && let Some((idx, field)) = self.find_elements_field_for_element(
1332                        struct_def.fields,
1333                        key.name.as_ref(),
1334                        key.namespace.as_deref(),
1335                        ns_all,
1336                    ) {
1337                        // Start or continue the list for this elements field
1338                        match elements_field_state {
1339                            None => {
1340                                // Start new list
1341                                wip = wip
1342                                    .begin_nth_field(idx)
1343                                    .map_err(DeserializeError::reflect)?;
1344                                wip = wip.begin_list().map_err(DeserializeError::reflect)?;
1345                                elements_field_state = Some((idx, true));
1346                                fields_set[idx] = true;
1347                            }
1348                            Some((current_idx, true)) if current_idx != idx => {
1349                                // Switching to a different xml::elements field
1350                                wip = wip.end().map_err(DeserializeError::reflect)?; // end field only
1351                                wip = wip
1352                                    .begin_nth_field(idx)
1353                                    .map_err(DeserializeError::reflect)?;
1354                                wip = wip.begin_list().map_err(DeserializeError::reflect)?;
1355                                elements_field_state = Some((idx, true));
1356                                fields_set[idx] = true;
1357                            }
1358                            Some((current_idx, true)) if current_idx == idx => {
1359                                // Continue adding to same list
1360                            }
1361                            _ => {}
1362                        }
1363
1364                        // Add item to list
1365                        wip = wip.begin_list_item().map_err(DeserializeError::reflect)?;
1366
1367                        // For enum item types, we need to select the variant based on element name
1368                        let item_shape = Self::get_list_item_shape(field.shape());
1369                        if let Some(item_shape) = item_shape {
1370                            if let Type::User(UserType::Enum(enum_def)) = &item_shape.ty {
1371                                // Find matching variant
1372                                if let Some(variant_idx) =
1373                                    Self::find_variant_for_element(enum_def, key.name.as_ref())
1374                                {
1375                                    wip = wip
1376                                        .select_nth_variant(variant_idx)
1377                                        .map_err(DeserializeError::reflect)?;
1378                                    // After selecting variant, deserialize the variant content
1379                                    wip = self.deserialize_enum_variant_content(wip)?;
1380                                } else {
1381                                    // No matching variant - deserialize directly
1382                                    wip = self.deserialize_into(wip)?;
1383                                }
1384                            } else {
1385                                // Not an enum - deserialize directly
1386                                wip = self.deserialize_into(wip)?;
1387                            }
1388                        } else {
1389                            wip = self.deserialize_into(wip)?;
1390                        }
1391
1392                        wip = wip.end().map_err(DeserializeError::reflect)?; // end list item
1393                        continue;
1394                    }
1395
1396                    // Check flattened fields for a match
1397                    let mut found_flatten = false;
1398                    for (flatten_idx, field) in struct_def.fields.iter().enumerate() {
1399                        if !field.is_flattened() {
1400                            continue;
1401                        }
1402                        if let Some((inner_fields, inner_set)) = flatten_info[flatten_idx].as_mut()
1403                        {
1404                            let inner_match = inner_fields.iter().enumerate().find(|(_, f)| {
1405                                Self::field_matches_with_namespace(
1406                                    f,
1407                                    key.name.as_ref(),
1408                                    key.namespace.as_deref(),
1409                                    key.location,
1410                                    ns_all,
1411                                )
1412                            });
1413
1414                            if let Some((inner_idx, _inner_field)) = inner_match {
1415                                // Check if flatten field is Option - if so, wrap in Some
1416                                let is_option = matches!(field.shape().def, Def::Option(_));
1417                                wip = wip
1418                                    .begin_nth_field(flatten_idx)
1419                                    .map_err(DeserializeError::reflect)?;
1420                                if is_option {
1421                                    wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1422                                }
1423                                wip = wip
1424                                    .begin_nth_field(inner_idx)
1425                                    .map_err(DeserializeError::reflect)?;
1426                                wip = self.deserialize_into(wip)?;
1427                                wip = wip.end().map_err(DeserializeError::reflect)?;
1428                                if is_option {
1429                                    wip = wip.end().map_err(DeserializeError::reflect)?;
1430                                }
1431                                wip = wip.end().map_err(DeserializeError::reflect)?;
1432                                inner_set[inner_idx] = true;
1433                                fields_set[flatten_idx] = true;
1434                                found_flatten = true;
1435                                break;
1436                            }
1437                        }
1438                    }
1439
1440                    if found_flatten {
1441                        continue;
1442                    }
1443
1444                    // Check if this unknown field should go to a DynamicValue flatten
1445                    let mut found_dynamic = false;
1446                    for (flatten_idx, _field) in struct_def.fields.iter().enumerate() {
1447                        if !dynamic_value_flattens[flatten_idx] {
1448                            continue;
1449                        }
1450
1451                        // This is a DynamicValue flatten - insert the field into it
1452                        // First, ensure the DynamicValue is initialized as an object
1453                        let is_option =
1454                            matches!(struct_def.fields[flatten_idx].shape().def, Def::Option(_));
1455
1456                        // Navigate to the DynamicValue field
1457                        if !fields_set[flatten_idx] {
1458                            // First time - need to initialize
1459                            wip = wip
1460                                .begin_nth_field(flatten_idx)
1461                                .map_err(DeserializeError::reflect)?;
1462                            if is_option {
1463                                wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1464                            }
1465                            // Initialize the DynamicValue as an object
1466                            wip = wip.begin_map().map_err(DeserializeError::reflect)?;
1467                            fields_set[flatten_idx] = true;
1468                        } else {
1469                            // Already initialized - just navigate to it
1470                            wip = wip
1471                                .begin_nth_field(flatten_idx)
1472                                .map_err(DeserializeError::reflect)?;
1473                            if is_option {
1474                                wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1475                            }
1476                        }
1477
1478                        // Insert the key-value pair into the object
1479                        wip = wip
1480                            .begin_object_entry(key.name.as_ref())
1481                            .map_err(DeserializeError::reflect)?;
1482                        wip = self.deserialize_into(wip)?;
1483                        wip = wip.end().map_err(DeserializeError::reflect)?;
1484
1485                        // Navigate back out (Note: we close the map when we're done with ALL fields, not per-field)
1486                        if is_option {
1487                            wip = wip.end().map_err(DeserializeError::reflect)?;
1488                        }
1489                        wip = wip.end().map_err(DeserializeError::reflect)?;
1490
1491                        found_dynamic = true;
1492                        break;
1493                    }
1494
1495                    if found_dynamic {
1496                        continue;
1497                    }
1498
1499                    // Check if this unknown field should go to a flattened map
1500                    if let Some(map_idx) = flatten_map_idx {
1501                        let field = &struct_def.fields[map_idx];
1502                        let is_option = matches!(field.shape().def, Def::Option(_));
1503
1504                        // Navigate to the map field
1505                        if !fields_set[map_idx] {
1506                            // First time - need to initialize the map
1507                            wip = wip
1508                                .begin_nth_field(map_idx)
1509                                .map_err(DeserializeError::reflect)?;
1510                            if is_option {
1511                                wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1512                            }
1513                            // Initialize the map
1514                            wip = wip.begin_map().map_err(DeserializeError::reflect)?;
1515                            fields_set[map_idx] = true;
1516                        } else {
1517                            // Already initialized - navigate to it
1518                            wip = wip
1519                                .begin_nth_field(map_idx)
1520                                .map_err(DeserializeError::reflect)?;
1521                            if is_option {
1522                                wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1523                            }
1524                        }
1525
1526                        // Insert the key-value pair into the map using begin_key/begin_value
1527                        // Clone the key to an owned String since we need it beyond the parse event lifetime
1528                        let key_owned: alloc::string::String = key.name.clone().into_owned();
1529                        // First: push key frame
1530                        wip = wip.begin_key().map_err(DeserializeError::reflect)?;
1531                        // Set the key (it's a string)
1532                        wip = wip.set(key_owned).map_err(DeserializeError::reflect)?;
1533                        // Pop key frame
1534                        wip = wip.end().map_err(DeserializeError::reflect)?;
1535                        // Push value frame
1536                        wip = wip.begin_value().map_err(DeserializeError::reflect)?;
1537                        // Deserialize value
1538                        wip = self.deserialize_into(wip)?;
1539                        // Pop value frame
1540                        wip = wip.end().map_err(DeserializeError::reflect)?;
1541
1542                        // Navigate back out
1543                        if is_option {
1544                            wip = wip.end().map_err(DeserializeError::reflect)?;
1545                        }
1546                        wip = wip.end().map_err(DeserializeError::reflect)?;
1547                        continue;
1548                    }
1549
1550                    if deny_unknown_fields {
1551                        return Err(DeserializeError::UnknownField(key.name.into_owned()));
1552                    } else {
1553                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1554                    }
1555                }
1556                other => {
1557                    return Err(DeserializeError::TypeMismatch {
1558                        expected: "field key or struct end",
1559                        got: format!("{other:?}"),
1560                    });
1561                }
1562            }
1563        }
1564
1565        // Apply defaults for missing fields
1566        for (idx, field) in struct_def.fields.iter().enumerate() {
1567            if field.is_flattened() {
1568                // Handle DynamicValue flattens that received no fields
1569                if dynamic_value_flattens[idx] && !fields_set[idx] {
1570                    let is_option = matches!(field.shape().def, Def::Option(_));
1571
1572                    if is_option {
1573                        // Option<DynamicValue> with no fields -> set to None
1574                        wip = wip
1575                            .begin_nth_field(idx)
1576                            .map_err(DeserializeError::reflect)?;
1577                        wip = wip.set_default().map_err(DeserializeError::reflect)?;
1578                        wip = wip.end().map_err(DeserializeError::reflect)?;
1579                    } else {
1580                        // DynamicValue with no fields -> initialize as empty object
1581                        wip = wip
1582                            .begin_nth_field(idx)
1583                            .map_err(DeserializeError::reflect)?;
1584                        // Initialize as object (for DynamicValue, begin_map creates an object)
1585                        wip = wip.begin_map().map_err(DeserializeError::reflect)?;
1586                        // The map is now initialized and empty, just end the field
1587                        wip = wip.end().map_err(DeserializeError::reflect)?;
1588                    }
1589                    continue;
1590                }
1591
1592                // Handle flattened map that received no unknown keys
1593                if flatten_map_idx == Some(idx) && !fields_set[idx] {
1594                    let is_option = matches!(field.shape().def, Def::Option(_));
1595                    let field_has_default = field.has_default();
1596                    let field_type_has_default =
1597                        field.shape().is(facet_core::Characteristic::Default);
1598
1599                    if is_option {
1600                        // Option<HashMap> with no fields -> set to None
1601                        wip = wip
1602                            .begin_nth_field(idx)
1603                            .map_err(DeserializeError::reflect)?;
1604                        wip = wip.set_default().map_err(DeserializeError::reflect)?;
1605                        wip = wip.end().map_err(DeserializeError::reflect)?;
1606                    } else if field_has_default || (struct_has_default && field_type_has_default) {
1607                        // Has default - use it
1608                        wip = wip
1609                            .set_nth_field_to_default(idx)
1610                            .map_err(DeserializeError::reflect)?;
1611                    } else {
1612                        // No default - initialize as empty map
1613                        wip = wip
1614                            .begin_nth_field(idx)
1615                            .map_err(DeserializeError::reflect)?;
1616                        wip = wip.begin_map().map_err(DeserializeError::reflect)?;
1617                        wip = wip.end().map_err(DeserializeError::reflect)?;
1618                    }
1619                    continue;
1620                }
1621
1622                if let Some((inner_fields, inner_set)) = flatten_info[idx].as_ref() {
1623                    let any_inner_set = inner_set.iter().any(|&s| s);
1624                    let is_option = matches!(field.shape().def, Def::Option(_));
1625
1626                    if any_inner_set {
1627                        // Some inner fields were set - apply defaults to missing ones
1628                        wip = wip
1629                            .begin_nth_field(idx)
1630                            .map_err(DeserializeError::reflect)?;
1631                        if is_option {
1632                            wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1633                        }
1634                        for (inner_idx, inner_field) in inner_fields.iter().enumerate() {
1635                            if inner_set[inner_idx] {
1636                                continue;
1637                            }
1638                            let inner_has_default = inner_field.has_default();
1639                            let inner_type_has_default =
1640                                inner_field.shape().is(Characteristic::Default);
1641                            let inner_is_option = matches!(inner_field.shape().def, Def::Option(_));
1642
1643                            if inner_has_default || inner_type_has_default {
1644                                wip = wip
1645                                    .set_nth_field_to_default(inner_idx)
1646                                    .map_err(DeserializeError::reflect)?;
1647                            } else if inner_is_option {
1648                                wip = wip
1649                                    .begin_nth_field(inner_idx)
1650                                    .map_err(DeserializeError::reflect)?;
1651                                wip = wip.set_default().map_err(DeserializeError::reflect)?;
1652                                wip = wip.end().map_err(DeserializeError::reflect)?;
1653                            } else if inner_field.should_skip_deserializing() {
1654                                wip = wip
1655                                    .set_nth_field_to_default(inner_idx)
1656                                    .map_err(DeserializeError::reflect)?;
1657                            } else {
1658                                return Err(DeserializeError::TypeMismatch {
1659                                    expected: "field to be present or have default",
1660                                    got: format!("missing field '{}'", inner_field.name),
1661                                });
1662                            }
1663                        }
1664                        if is_option {
1665                            wip = wip.end().map_err(DeserializeError::reflect)?;
1666                        }
1667                        wip = wip.end().map_err(DeserializeError::reflect)?;
1668                    } else if is_option {
1669                        // No inner fields set and field is Option - set to None
1670                        wip = wip
1671                            .begin_nth_field(idx)
1672                            .map_err(DeserializeError::reflect)?;
1673                        wip = wip.set_default().map_err(DeserializeError::reflect)?;
1674                        wip = wip.end().map_err(DeserializeError::reflect)?;
1675                    } else {
1676                        // No inner fields set - try to default the whole flattened field
1677                        let field_has_default = field.has_default();
1678                        let field_type_has_default = field.shape().is(Characteristic::Default);
1679                        if field_has_default || (struct_has_default && field_type_has_default) {
1680                            wip = wip
1681                                .set_nth_field_to_default(idx)
1682                                .map_err(DeserializeError::reflect)?;
1683                        } else {
1684                            let all_inner_can_default = inner_fields.iter().all(|f| {
1685                                f.has_default()
1686                                    || f.shape().is(Characteristic::Default)
1687                                    || matches!(f.shape().def, Def::Option(_))
1688                                    || f.should_skip_deserializing()
1689                            });
1690                            if all_inner_can_default {
1691                                wip = wip
1692                                    .begin_nth_field(idx)
1693                                    .map_err(DeserializeError::reflect)?;
1694                                for (inner_idx, inner_field) in inner_fields.iter().enumerate() {
1695                                    let inner_has_default = inner_field.has_default();
1696                                    let inner_type_has_default =
1697                                        inner_field.shape().is(Characteristic::Default);
1698                                    let inner_is_option =
1699                                        matches!(inner_field.shape().def, Def::Option(_));
1700
1701                                    if inner_has_default || inner_type_has_default {
1702                                        wip = wip
1703                                            .set_nth_field_to_default(inner_idx)
1704                                            .map_err(DeserializeError::reflect)?;
1705                                    } else if inner_is_option {
1706                                        wip = wip
1707                                            .begin_nth_field(inner_idx)
1708                                            .map_err(DeserializeError::reflect)?;
1709                                        wip =
1710                                            wip.set_default().map_err(DeserializeError::reflect)?;
1711                                        wip = wip.end().map_err(DeserializeError::reflect)?;
1712                                    } else if inner_field.should_skip_deserializing() {
1713                                        wip = wip
1714                                            .set_nth_field_to_default(inner_idx)
1715                                            .map_err(DeserializeError::reflect)?;
1716                                    }
1717                                }
1718                                wip = wip.end().map_err(DeserializeError::reflect)?;
1719                            } else {
1720                                return Err(DeserializeError::TypeMismatch {
1721                                    expected: "field to be present or have default",
1722                                    got: format!("missing flattened field '{}'", field.name),
1723                                });
1724                            }
1725                        }
1726                    }
1727                }
1728                continue;
1729            }
1730
1731            if fields_set[idx] {
1732                continue;
1733            }
1734
1735            let field_has_default = field.has_default();
1736            let field_type_has_default = field.shape().is(Characteristic::Default);
1737            let field_is_option = matches!(field.shape().def, Def::Option(_));
1738
1739            if field_has_default || (struct_has_default && field_type_has_default) {
1740                wip = wip
1741                    .set_nth_field_to_default(idx)
1742                    .map_err(DeserializeError::reflect)?;
1743            } else if field_is_option {
1744                wip = wip
1745                    .begin_field(field.name)
1746                    .map_err(DeserializeError::reflect)?;
1747                wip = wip.set_default().map_err(DeserializeError::reflect)?;
1748                wip = wip.end().map_err(DeserializeError::reflect)?;
1749            } else if field.should_skip_deserializing() {
1750                wip = wip
1751                    .set_nth_field_to_default(idx)
1752                    .map_err(DeserializeError::reflect)?;
1753            } else {
1754                return Err(DeserializeError::TypeMismatch {
1755                    expected: "field to be present or have default",
1756                    got: format!("missing field '{}'", field.name),
1757                });
1758            }
1759        }
1760
1761        // Finish deferred mode (only if we started it)
1762        if !already_deferred {
1763            wip = wip.finish_deferred().map_err(DeserializeError::reflect)?;
1764        }
1765
1766        Ok(wip)
1767    }
1768
1769    /// Deserialize a struct with flattened fields using facet-solver.
1770    ///
1771    /// This uses the solver's Schema/Resolution to handle arbitrarily nested
1772    /// flatten structures by looking up the full path for each field.
1773    /// It also handles flattened enums by using probing to collect keys first,
1774    /// then using the Solver to disambiguate between resolutions.
1775    fn deserialize_struct_with_flatten(
1776        &mut self,
1777        mut wip: Partial<'input, BORROW>,
1778    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1779        use alloc::collections::BTreeSet;
1780        use facet_core::Characteristic;
1781        use facet_reflect::Resolution;
1782        use facet_solver::{PathSegment, Schema, Solver};
1783
1784        let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
1785
1786        // Build the schema for this type - this recursively expands all flatten fields
1787        let schema = Schema::build_auto(wip.shape())
1788            .map_err(|e| DeserializeError::Unsupported(format!("failed to build schema: {e}")))?;
1789
1790        // Check if we have multiple resolutions (i.e., flattened enums)
1791        let resolutions = schema.resolutions();
1792        if resolutions.is_empty() {
1793            return Err(DeserializeError::Unsupported(
1794                "schema has no resolutions".into(),
1795            ));
1796        }
1797
1798        // ========== PASS 1: Probe to collect all field keys ==========
1799        let probe = self
1800            .parser
1801            .begin_probe()
1802            .map_err(DeserializeError::Parser)?;
1803        let evidence = Self::collect_evidence(probe).map_err(DeserializeError::Parser)?;
1804
1805        // Feed keys to solver to narrow down resolutions
1806        let mut solver = Solver::new(&schema);
1807        for ev in &evidence {
1808            solver.see_key(ev.name.clone());
1809        }
1810
1811        // Get the resolved configuration
1812        let config_handle = solver
1813            .finish()
1814            .map_err(|e| DeserializeError::Unsupported(format!("solver failed: {e}")))?;
1815        let resolution = config_handle.resolution();
1816
1817        // ========== PASS 2: Parse the struct with resolved paths ==========
1818        // Expect StructStart
1819        let event = self.expect_event("value")?;
1820        if !matches!(event, ParseEvent::StructStart(_)) {
1821            return Err(DeserializeError::TypeMismatch {
1822                expected: "struct start",
1823                got: format!("{event:?}"),
1824            });
1825        }
1826
1827        // Enter deferred mode for flatten handling (if not already in deferred mode)
1828        let already_deferred = wip.is_deferred();
1829        if !already_deferred {
1830            let reflect_resolution = Resolution::new();
1831            wip = wip
1832                .begin_deferred(reflect_resolution)
1833                .map_err(DeserializeError::reflect)?;
1834        }
1835
1836        // Track which fields have been set (by serialized name - uses 'static str from resolution)
1837        let mut fields_set: BTreeSet<&'static str> = BTreeSet::new();
1838
1839        // Track currently open path segments: (field_name, is_option, is_variant)
1840        // The is_variant flag indicates if we've selected a variant at this level
1841        let mut open_segments: alloc::vec::Vec<(&str, bool, bool)> = alloc::vec::Vec::new();
1842
1843        loop {
1844            let event = self.expect_event("value")?;
1845            match event {
1846                ParseEvent::StructEnd => break,
1847                ParseEvent::FieldKey(key) => {
1848                    // Look up field in the resolution
1849                    if let Some(field_info) = resolution.field(key.name.as_ref()) {
1850                        let segments = field_info.path.segments();
1851
1852                        // Check if this path ends with a Variant segment (externally-tagged enum)
1853                        let ends_with_variant = segments
1854                            .last()
1855                            .is_some_and(|s| matches!(s, PathSegment::Variant(_, _)));
1856
1857                        // Extract field names from the path (excluding trailing Variant)
1858                        let field_segments: alloc::vec::Vec<&str> = segments
1859                            .iter()
1860                            .filter_map(|s| match s {
1861                                PathSegment::Field(name) => Some(*name),
1862                                PathSegment::Variant(_, _) => None,
1863                            })
1864                            .collect();
1865
1866                        // Find common prefix with currently open segments
1867                        let common_len = open_segments
1868                            .iter()
1869                            .zip(field_segments.iter())
1870                            .take_while(|((name, _, _), b)| *name == **b)
1871                            .count();
1872
1873                        // Close segments that are no longer needed (in reverse order)
1874                        while open_segments.len() > common_len {
1875                            let (_, is_option, _) = open_segments.pop().unwrap();
1876                            if is_option {
1877                                wip = wip.end().map_err(DeserializeError::reflect)?;
1878                            }
1879                            wip = wip.end().map_err(DeserializeError::reflect)?;
1880                        }
1881
1882                        // Open new segments
1883                        for &segment in &field_segments[common_len..] {
1884                            wip = wip
1885                                .begin_field(segment)
1886                                .map_err(DeserializeError::reflect)?;
1887                            let is_option = matches!(wip.shape().def, Def::Option(_));
1888                            if is_option {
1889                                wip = wip.begin_some().map_err(DeserializeError::reflect)?;
1890                            }
1891                            open_segments.push((segment, is_option, false));
1892                        }
1893
1894                        if ends_with_variant {
1895                            // For externally-tagged enums: select variant and deserialize content
1896                            if let Some(PathSegment::Variant(_, variant_name)) = segments.last() {
1897                                wip = wip
1898                                    .select_variant_named(variant_name)
1899                                    .map_err(DeserializeError::reflect)?;
1900                                // Deserialize the variant's struct content (the nested object)
1901                                wip = self.deserialize_variant_struct_fields(wip)?;
1902                            }
1903                        } else {
1904                            // Regular field: deserialize into it
1905                            wip = self.deserialize_into(wip)?;
1906                        }
1907
1908                        // Close segments we just opened (we're done with this field)
1909                        while open_segments.len() > common_len {
1910                            let (_, is_option, _) = open_segments.pop().unwrap();
1911                            if is_option {
1912                                wip = wip.end().map_err(DeserializeError::reflect)?;
1913                            }
1914                            wip = wip.end().map_err(DeserializeError::reflect)?;
1915                        }
1916
1917                        // Store the static serialized_name from the resolution
1918                        fields_set.insert(field_info.serialized_name);
1919                        continue;
1920                    }
1921
1922                    if deny_unknown_fields {
1923                        return Err(DeserializeError::UnknownField(key.name.into_owned()));
1924                    } else {
1925                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1926                    }
1927                }
1928                other => {
1929                    return Err(DeserializeError::TypeMismatch {
1930                        expected: "field key or struct end",
1931                        got: format!("{other:?}"),
1932                    });
1933                }
1934            }
1935        }
1936
1937        // Close any remaining open segments
1938        while let Some((_, is_option, _)) = open_segments.pop() {
1939            if is_option {
1940                wip = wip.end().map_err(DeserializeError::reflect)?;
1941            }
1942            wip = wip.end().map_err(DeserializeError::reflect)?;
1943        }
1944
1945        // Handle missing fields - apply defaults
1946        // Get all fields sorted by path depth (deepest first for proper default handling)
1947        let all_fields = resolution.deserialization_order();
1948
1949        // Track which top-level flatten fields have had any sub-fields set
1950        let mut touched_top_fields: BTreeSet<&str> = BTreeSet::new();
1951        for field_name in &fields_set {
1952            if let Some(info) = resolution.field(field_name)
1953                && let Some(PathSegment::Field(top)) = info.path.segments().first()
1954            {
1955                touched_top_fields.insert(*top);
1956            }
1957        }
1958
1959        for field_info in all_fields {
1960            if fields_set.contains(field_info.serialized_name) {
1961                continue;
1962            }
1963
1964            // Skip fields that end with Variant - these are handled by enum deserialization
1965            let ends_with_variant = field_info
1966                .path
1967                .segments()
1968                .last()
1969                .is_some_and(|s| matches!(s, PathSegment::Variant(_, _)));
1970            if ends_with_variant {
1971                continue;
1972            }
1973
1974            let path_segments: alloc::vec::Vec<&str> = field_info
1975                .path
1976                .segments()
1977                .iter()
1978                .filter_map(|s| match s {
1979                    PathSegment::Field(name) => Some(*name),
1980                    PathSegment::Variant(_, _) => None,
1981                })
1982                .collect();
1983
1984            // Check if this field's parent was touched
1985            let first_segment = path_segments.first().copied();
1986            let parent_touched = first_segment
1987                .map(|s| touched_top_fields.contains(s))
1988                .unwrap_or(false);
1989
1990            // If parent wasn't touched at all, we might default the whole parent
1991            // For now, handle individual field defaults
1992            let field_has_default = field_info.field.has_default();
1993            let field_type_has_default = field_info.value_shape.is(Characteristic::Default);
1994            let field_is_option = matches!(field_info.value_shape.def, Def::Option(_));
1995
1996            if field_has_default
1997                || field_type_has_default
1998                || field_is_option
1999                || field_info.field.should_skip_deserializing()
2000            {
2001                // Navigate to the field and set default
2002                for &segment in &path_segments[..path_segments.len().saturating_sub(1)] {
2003                    wip = wip
2004                        .begin_field(segment)
2005                        .map_err(DeserializeError::reflect)?;
2006                    if matches!(wip.shape().def, Def::Option(_)) {
2007                        wip = wip.begin_some().map_err(DeserializeError::reflect)?;
2008                    }
2009                }
2010
2011                if let Some(&last) = path_segments.last() {
2012                    wip = wip.begin_field(last).map_err(DeserializeError::reflect)?;
2013                    wip = wip.set_default().map_err(DeserializeError::reflect)?;
2014                    wip = wip.end().map_err(DeserializeError::reflect)?;
2015                }
2016
2017                // Close the path we opened
2018                for _ in 0..path_segments.len().saturating_sub(1) {
2019                    // Need to check if we're in an option
2020                    wip = wip.end().map_err(DeserializeError::reflect)?;
2021                }
2022            } else if !parent_touched && path_segments.len() > 1 {
2023                // Parent wasn't touched and field has no default - this is OK if the whole
2024                // parent can be defaulted (handled by deferred mode)
2025                continue;
2026            } else if field_info.required {
2027                return Err(DeserializeError::TypeMismatch {
2028                    expected: "field to be present or have default",
2029                    got: format!("missing field '{}'", field_info.serialized_name),
2030                });
2031            }
2032        }
2033
2034        // Finish deferred mode (only if we started it)
2035        if !already_deferred {
2036            wip = wip.finish_deferred().map_err(DeserializeError::reflect)?;
2037        }
2038
2039        Ok(wip)
2040    }
2041
2042    /// Deserialize the struct fields of a variant.
2043    /// Expects the variant to already be selected.
2044    fn deserialize_variant_struct_fields(
2045        &mut self,
2046        mut wip: Partial<'input, BORROW>,
2047    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2048        use facet_core::StructKind;
2049
2050        let variant = wip
2051            .selected_variant()
2052            .ok_or_else(|| DeserializeError::TypeMismatch {
2053                expected: "selected variant",
2054                got: "no variant selected".into(),
2055            })?;
2056
2057        let variant_fields = variant.data.fields;
2058        let kind = variant.data.kind;
2059
2060        // Handle based on variant kind
2061        match kind {
2062            StructKind::TupleStruct if variant_fields.len() == 1 => {
2063                // Single-element tuple variant (newtype): deserialize the inner value directly
2064                wip = wip.begin_nth_field(0).map_err(DeserializeError::reflect)?;
2065                wip = self.deserialize_into(wip)?;
2066                wip = wip.end().map_err(DeserializeError::reflect)?;
2067                return Ok(wip);
2068            }
2069            StructKind::TupleStruct | StructKind::Tuple => {
2070                // Multi-element tuple variant - not yet supported in this context
2071                return Err(DeserializeError::Unsupported(
2072                    "multi-element tuple variants in flatten not yet supported".into(),
2073                ));
2074            }
2075            StructKind::Unit => {
2076                // Unit variant - nothing to deserialize
2077                return Ok(wip);
2078            }
2079            StructKind::Struct => {
2080                // Struct variant - fall through to struct deserialization below
2081            }
2082        }
2083
2084        // Struct variant: deserialize as a struct with named fields
2085        // Expect StructStart for the variant content
2086        let event = self.expect_event("value")?;
2087        if !matches!(event, ParseEvent::StructStart(_)) {
2088            return Err(DeserializeError::TypeMismatch {
2089                expected: "struct start for variant content",
2090                got: format!("{event:?}"),
2091            });
2092        }
2093
2094        // Track which fields have been set
2095        let num_fields = variant_fields.len();
2096        let mut fields_set = alloc::vec![false; num_fields];
2097
2098        // Process all fields
2099        loop {
2100            let event = self.expect_event("value")?;
2101            match event {
2102                ParseEvent::StructEnd => break,
2103                ParseEvent::FieldKey(key) => {
2104                    // Look up field in variant's fields
2105                    let field_info = variant_fields.iter().enumerate().find(|(_, f)| {
2106                        Self::field_matches_with_namespace(
2107                            f,
2108                            key.name.as_ref(),
2109                            key.namespace.as_deref(),
2110                            key.location,
2111                            None,
2112                        )
2113                    });
2114
2115                    if let Some((idx, _field)) = field_info {
2116                        wip = wip
2117                            .begin_nth_field(idx)
2118                            .map_err(DeserializeError::reflect)?;
2119                        wip = self.deserialize_into(wip)?;
2120                        wip = wip.end().map_err(DeserializeError::reflect)?;
2121                        fields_set[idx] = true;
2122                    } else {
2123                        // Unknown field - skip
2124                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
2125                    }
2126                }
2127                other => {
2128                    return Err(DeserializeError::TypeMismatch {
2129                        expected: "field key or struct end",
2130                        got: format!("{other:?}"),
2131                    });
2132                }
2133            }
2134        }
2135
2136        // Apply defaults for missing fields
2137        for (idx, field) in variant_fields.iter().enumerate() {
2138            if fields_set[idx] {
2139                continue;
2140            }
2141
2142            let field_has_default = field.has_default();
2143            let field_type_has_default = field.shape().is(facet_core::Characteristic::Default);
2144            let field_is_option = matches!(field.shape().def, Def::Option(_));
2145
2146            if field_has_default || field_type_has_default {
2147                wip = wip
2148                    .set_nth_field_to_default(idx)
2149                    .map_err(DeserializeError::reflect)?;
2150            } else if field_is_option {
2151                wip = wip
2152                    .begin_nth_field(idx)
2153                    .map_err(DeserializeError::reflect)?;
2154                wip = wip.set_default().map_err(DeserializeError::reflect)?;
2155                wip = wip.end().map_err(DeserializeError::reflect)?;
2156            } else if field.should_skip_deserializing() {
2157                wip = wip
2158                    .set_nth_field_to_default(idx)
2159                    .map_err(DeserializeError::reflect)?;
2160            } else {
2161                return Err(DeserializeError::TypeMismatch {
2162                    expected: "field to be present or have default",
2163                    got: format!("missing field '{}'", field.name),
2164                });
2165            }
2166        }
2167
2168        Ok(wip)
2169    }
2170
2171    /// Deserialize into a type with span metadata (like `Spanned<T>`).
2172    ///
2173    /// This handles structs that have:
2174    /// - One or more non-metadata fields (the actual values to deserialize)
2175    /// - A field with `#[facet(metadata = span)]` to store source location
2176    ///
2177    /// The metadata field is populated with a default span since most format parsers
2178    /// don't track source locations.
2179    fn deserialize_spanned(
2180        &mut self,
2181        mut wip: Partial<'input, BORROW>,
2182    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2183        let shape = wip.shape();
2184
2185        // Find the span metadata field and non-metadata fields
2186        let Type::User(UserType::Struct(struct_def)) = &shape.ty else {
2187            return Err(DeserializeError::Unsupported(format!(
2188                "expected struct with span metadata, found {}",
2189                shape.type_identifier
2190            )));
2191        };
2192
2193        let span_field = struct_def
2194            .fields
2195            .iter()
2196            .find(|f| f.metadata_kind() == Some("span"))
2197            .ok_or_else(|| {
2198                DeserializeError::Unsupported(format!(
2199                    "expected struct with span metadata field, found {}",
2200                    shape.type_identifier
2201                ))
2202            })?;
2203
2204        let value_fields: alloc::vec::Vec<_> = struct_def
2205            .fields
2206            .iter()
2207            .filter(|f| !f.is_metadata())
2208            .collect();
2209
2210        // Deserialize all non-metadata fields transparently
2211        // For the common case (Spanned<T> with a single "value" field), this is just one field
2212        for field in value_fields {
2213            wip = wip
2214                .begin_field(field.name)
2215                .map_err(DeserializeError::reflect)?;
2216            wip = self.deserialize_into(wip)?;
2217            wip = wip.end().map_err(DeserializeError::reflect)?;
2218        }
2219
2220        // Set the span metadata field to default
2221        // Most format parsers don't track source spans, so we use a default (unknown) span
2222        wip = wip
2223            .begin_field(span_field.name)
2224            .map_err(DeserializeError::reflect)?;
2225        wip = wip.set_default().map_err(DeserializeError::reflect)?;
2226        wip = wip.end().map_err(DeserializeError::reflect)?;
2227
2228        Ok(wip)
2229    }
2230
2231    fn deserialize_tuple(
2232        &mut self,
2233        mut wip: Partial<'input, BORROW>,
2234    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2235        // Get field count for tuple hints (needed for non-self-describing formats like postcard)
2236        let field_count = match &wip.shape().ty {
2237            Type::User(UserType::Struct(def)) => def.fields.len(),
2238            _ => 0, // Unit type or unknown - will be handled below
2239        };
2240
2241        // Hint to non-self-describing parsers how many fields to expect
2242        // Tuples are like positional structs, so we use hint_struct_fields
2243        self.parser.hint_struct_fields(field_count);
2244
2245        let event = self.expect_peek("value")?;
2246
2247        // Special case: newtype structs (single-field tuple structs) can accept scalar values
2248        // directly without requiring a sequence wrapper. This enables patterns like:
2249        //   struct Wrapper(i32);
2250        //   toml: "value = 42"  ->  Wrapper(42)
2251        if field_count == 1 && matches!(event, ParseEvent::Scalar(_)) {
2252            // Unwrap into field "0" and deserialize the scalar
2253            wip = wip.begin_field("0").map_err(DeserializeError::reflect)?;
2254            wip = self.deserialize_into(wip)?;
2255            wip = wip.end().map_err(DeserializeError::reflect)?;
2256            return Ok(wip);
2257        }
2258
2259        let event = self.expect_event("value")?;
2260
2261        // Accept either SequenceStart (JSON arrays) or StructStart (for XML elements or
2262        // non-self-describing formats like postcard where tuples are positional structs)
2263        let struct_mode = match event {
2264            ParseEvent::SequenceStart(_) => false,
2265            // Ambiguous containers (XML elements) always use struct mode
2266            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
2267            // For non-self-describing formats, StructStart(Object) is valid for tuples
2268            // because hint_struct_fields was called and tuples are positional structs
2269            ParseEvent::StructStart(_) if !self.parser.is_self_describing() => true,
2270            // For self-describing formats like TOML/JSON, objects with numeric keys
2271            // (e.g., { "0" = true, "1" = 1 }) are valid tuple representations
2272            ParseEvent::StructStart(ContainerKind::Object) => true,
2273            ParseEvent::StructStart(kind) => {
2274                return Err(DeserializeError::TypeMismatch {
2275                    expected: "array",
2276                    got: kind.name().into(),
2277                });
2278            }
2279            _ => {
2280                return Err(DeserializeError::TypeMismatch {
2281                    expected: "sequence start for tuple",
2282                    got: format!("{event:?}"),
2283                });
2284            }
2285        };
2286
2287        let mut index = 0usize;
2288        loop {
2289            let event = self.expect_peek("value")?;
2290
2291            // Check for end of container
2292            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
2293                self.expect_event("value")?;
2294                break;
2295            }
2296
2297            // In struct mode, skip FieldKey events
2298            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
2299                self.expect_event("value")?;
2300                continue;
2301            }
2302
2303            // Select field by index
2304            let field_name = alloc::string::ToString::to_string(&index);
2305            wip = wip
2306                .begin_field(&field_name)
2307                .map_err(DeserializeError::reflect)?;
2308            wip = self.deserialize_into(wip)?;
2309            wip = wip.end().map_err(DeserializeError::reflect)?;
2310            index += 1;
2311        }
2312
2313        Ok(wip)
2314    }
2315
2316    fn deserialize_enum(
2317        &mut self,
2318        wip: Partial<'input, BORROW>,
2319    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2320        let shape = wip.shape();
2321
2322        // Hint to non-self-describing parsers what variant metadata to expect
2323        if let Type::User(UserType::Enum(enum_def)) = &shape.ty {
2324            let variant_hints: Vec<crate::EnumVariantHint> = enum_def
2325                .variants
2326                .iter()
2327                .map(|v| crate::EnumVariantHint {
2328                    name: v.name,
2329                    kind: v.data.kind,
2330                    field_count: v.data.fields.len(),
2331                })
2332                .collect();
2333            self.parser.hint_enum(&variant_hints);
2334        }
2335
2336        // Check for different tagging modes
2337        let tag_attr = shape.get_tag_attr();
2338        let content_attr = shape.get_content_attr();
2339        let is_numeric = shape.is_numeric();
2340        let is_untagged = shape.is_untagged();
2341
2342        if is_numeric {
2343            return self.deserialize_numeric_enum(wip);
2344        }
2345
2346        // Determine tagging mode
2347        if is_untagged {
2348            return self.deserialize_enum_untagged(wip);
2349        }
2350
2351        if let (Some(tag_key), Some(content_key)) = (tag_attr, content_attr) {
2352            // Adjacently tagged: {"t": "VariantName", "c": {...}}
2353            return self.deserialize_enum_adjacently_tagged(wip, tag_key, content_key);
2354        }
2355
2356        if let Some(tag_key) = tag_attr {
2357            // Internally tagged: {"type": "VariantName", ...fields...}
2358            return self.deserialize_enum_internally_tagged(wip, tag_key);
2359        }
2360
2361        // Externally tagged (default): {"VariantName": {...}} or just "VariantName"
2362        self.deserialize_enum_externally_tagged(wip)
2363    }
2364
2365    fn deserialize_enum_externally_tagged(
2366        &mut self,
2367        mut wip: Partial<'input, BORROW>,
2368    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2369        let event = self.expect_peek("value")?;
2370
2371        // Check for unit variant (just a string)
2372        if let ParseEvent::Scalar(ScalarValue::Str(variant_name)) = &event {
2373            self.expect_event("value")?;
2374            wip = wip
2375                .select_variant_named(variant_name)
2376                .map_err(DeserializeError::reflect)?;
2377            return Ok(wip);
2378        }
2379
2380        // Otherwise expect a struct { VariantName: ... }
2381        if !matches!(event, ParseEvent::StructStart(_)) {
2382            return Err(DeserializeError::TypeMismatch {
2383                expected: "string or struct for enum",
2384                got: format!("{event:?}"),
2385            });
2386        }
2387
2388        self.expect_event("value")?; // consume StructStart
2389
2390        // Get the variant name
2391        let event = self.expect_event("value")?;
2392        let variant_name = match event {
2393            ParseEvent::FieldKey(key) => key.name,
2394            other => {
2395                return Err(DeserializeError::TypeMismatch {
2396                    expected: "variant name",
2397                    got: format!("{other:?}"),
2398                });
2399            }
2400        };
2401
2402        wip = wip
2403            .select_variant_named(&variant_name)
2404            .map_err(DeserializeError::reflect)?;
2405
2406        // Deserialize the variant content
2407        wip = self.deserialize_enum_variant_content(wip)?;
2408
2409        // Consume StructEnd
2410        let event = self.expect_event("value")?;
2411        if !matches!(event, ParseEvent::StructEnd) {
2412            return Err(DeserializeError::TypeMismatch {
2413                expected: "struct end after enum variant",
2414                got: format!("{event:?}"),
2415            });
2416        }
2417
2418        Ok(wip)
2419    }
2420
2421    fn deserialize_enum_internally_tagged(
2422        &mut self,
2423        mut wip: Partial<'input, BORROW>,
2424        tag_key: &str,
2425    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2426        use facet_core::Characteristic;
2427
2428        // Step 1: Probe to find the tag value (handles out-of-order fields)
2429        let probe = self
2430            .parser
2431            .begin_probe()
2432            .map_err(DeserializeError::Parser)?;
2433        let evidence = Self::collect_evidence(probe).map_err(DeserializeError::Parser)?;
2434
2435        let variant_name = Self::find_tag_value(&evidence, tag_key)
2436            .ok_or_else(|| DeserializeError::TypeMismatch {
2437                expected: "tag field in internally tagged enum",
2438                got: format!("missing '{tag_key}' field"),
2439            })?
2440            .to_string();
2441
2442        // Step 2: Consume StructStart
2443        let event = self.expect_event("value")?;
2444        if !matches!(event, ParseEvent::StructStart(_)) {
2445            return Err(DeserializeError::TypeMismatch {
2446                expected: "struct for internally tagged enum",
2447                got: format!("{event:?}"),
2448            });
2449        }
2450
2451        // Step 3: Select the variant
2452        wip = wip
2453            .select_variant_named(&variant_name)
2454            .map_err(DeserializeError::reflect)?;
2455
2456        // Get the selected variant info
2457        let variant = wip
2458            .selected_variant()
2459            .ok_or_else(|| DeserializeError::TypeMismatch {
2460                expected: "selected variant",
2461                got: "no variant selected".into(),
2462            })?;
2463
2464        let variant_fields = variant.data.fields;
2465
2466        // Check if this is a unit variant (no fields)
2467        if variant_fields.is_empty() || variant.data.kind == StructKind::Unit {
2468            // Consume remaining fields in the object
2469            loop {
2470                let event = self.expect_event("value")?;
2471                match event {
2472                    ParseEvent::StructEnd => break,
2473                    ParseEvent::FieldKey(_) => {
2474                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
2475                    }
2476                    other => {
2477                        return Err(DeserializeError::TypeMismatch {
2478                            expected: "field key or struct end",
2479                            got: format!("{other:?}"),
2480                        });
2481                    }
2482                }
2483            }
2484            return Ok(wip);
2485        }
2486
2487        // Track which fields have been set
2488        let num_fields = variant_fields.len();
2489        let mut fields_set = alloc::vec![false; num_fields];
2490
2491        // Step 4: Process all fields (they can come in any order now)
2492        loop {
2493            let event = self.expect_event("value")?;
2494            match event {
2495                ParseEvent::StructEnd => break,
2496                ParseEvent::FieldKey(key) => {
2497                    // Skip the tag field - already used
2498                    if key.name.as_ref() == tag_key {
2499                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
2500                        continue;
2501                    }
2502
2503                    // Look up field in variant's fields
2504                    // Uses namespace-aware matching when namespace is present
2505                    let field_info = variant_fields.iter().enumerate().find(|(_, f)| {
2506                        Self::field_matches_with_namespace(
2507                            f,
2508                            key.name.as_ref(),
2509                            key.namespace.as_deref(),
2510                            key.location,
2511                            None, // Enums don't have ns_all
2512                        )
2513                    });
2514
2515                    if let Some((idx, _field)) = field_info {
2516                        wip = wip
2517                            .begin_nth_field(idx)
2518                            .map_err(DeserializeError::reflect)?;
2519                        wip = self.deserialize_into(wip)?;
2520                        wip = wip.end().map_err(DeserializeError::reflect)?;
2521                        fields_set[idx] = true;
2522                    } else {
2523                        // Unknown field - skip
2524                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
2525                    }
2526                }
2527                other => {
2528                    return Err(DeserializeError::TypeMismatch {
2529                        expected: "field key or struct end",
2530                        got: format!("{other:?}"),
2531                    });
2532                }
2533            }
2534        }
2535
2536        // Apply defaults for missing fields
2537        for (idx, field) in variant_fields.iter().enumerate() {
2538            if fields_set[idx] {
2539                continue;
2540            }
2541
2542            let field_has_default = field.has_default();
2543            let field_type_has_default = field.shape().is(Characteristic::Default);
2544            let field_is_option = matches!(field.shape().def, Def::Option(_));
2545
2546            if field_has_default || field_type_has_default {
2547                wip = wip
2548                    .set_nth_field_to_default(idx)
2549                    .map_err(DeserializeError::reflect)?;
2550            } else if field_is_option {
2551                wip = wip
2552                    .begin_nth_field(idx)
2553                    .map_err(DeserializeError::reflect)?;
2554                wip = wip.set_default().map_err(DeserializeError::reflect)?;
2555                wip = wip.end().map_err(DeserializeError::reflect)?;
2556            } else if field.should_skip_deserializing() {
2557                wip = wip
2558                    .set_nth_field_to_default(idx)
2559                    .map_err(DeserializeError::reflect)?;
2560            } else {
2561                return Err(DeserializeError::TypeMismatch {
2562                    expected: "field to be present or have default",
2563                    got: format!("missing field '{}'", field.name),
2564                });
2565            }
2566        }
2567
2568        Ok(wip)
2569    }
2570
2571    /// Helper to find a tag value from field evidence.
2572    fn find_tag_value<'a>(
2573        evidence: &'a [crate::FieldEvidence<'input>],
2574        tag_key: &str,
2575    ) -> Option<&'a str> {
2576        evidence
2577            .iter()
2578            .find(|e| e.name == tag_key)
2579            .and_then(|e| match &e.scalar_value {
2580                Some(ScalarValue::Str(s)) => Some(s.as_ref()),
2581                _ => None,
2582            })
2583    }
2584
2585    /// Helper to collect all evidence from a probe stream.
2586    fn collect_evidence<S: crate::ProbeStream<'input, Error = P::Error>>(
2587        mut probe: S,
2588    ) -> Result<alloc::vec::Vec<crate::FieldEvidence<'input>>, P::Error> {
2589        let mut evidence = alloc::vec::Vec::new();
2590        while let Some(ev) = probe.next()? {
2591            evidence.push(ev);
2592        }
2593        Ok(evidence)
2594    }
2595
2596    fn deserialize_enum_adjacently_tagged(
2597        &mut self,
2598        mut wip: Partial<'input, BORROW>,
2599        tag_key: &str,
2600        content_key: &str,
2601    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2602        // Step 1: Probe to find the tag value (handles out-of-order fields)
2603        let probe = self
2604            .parser
2605            .begin_probe()
2606            .map_err(DeserializeError::Parser)?;
2607        let evidence = Self::collect_evidence(probe).map_err(DeserializeError::Parser)?;
2608
2609        let variant_name = Self::find_tag_value(&evidence, tag_key)
2610            .ok_or_else(|| DeserializeError::TypeMismatch {
2611                expected: "tag field in adjacently tagged enum",
2612                got: format!("missing '{tag_key}' field"),
2613            })?
2614            .to_string();
2615
2616        // Step 2: Consume StructStart
2617        let event = self.expect_event("value")?;
2618        if !matches!(event, ParseEvent::StructStart(_)) {
2619            return Err(DeserializeError::TypeMismatch {
2620                expected: "struct for adjacently tagged enum",
2621                got: format!("{event:?}"),
2622            });
2623        }
2624
2625        // Step 3: Select the variant
2626        wip = wip
2627            .select_variant_named(&variant_name)
2628            .map_err(DeserializeError::reflect)?;
2629
2630        // Step 4: Process fields in any order
2631        let mut content_seen = false;
2632        loop {
2633            let event = self.expect_event("value")?;
2634            match event {
2635                ParseEvent::StructEnd => break,
2636                ParseEvent::FieldKey(key) => {
2637                    if key.name.as_ref() == tag_key {
2638                        // Skip the tag field - already used
2639                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
2640                    } else if key.name.as_ref() == content_key {
2641                        // Deserialize the content
2642                        wip = self.deserialize_enum_variant_content(wip)?;
2643                        content_seen = true;
2644                    } else {
2645                        // Unknown field - skip
2646                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
2647                    }
2648                }
2649                other => {
2650                    return Err(DeserializeError::TypeMismatch {
2651                        expected: "field key or struct end",
2652                        got: format!("{other:?}"),
2653                    });
2654                }
2655            }
2656        }
2657
2658        // If no content field was present, it's a unit variant (already selected above)
2659        if !content_seen {
2660            // Check if the variant expects content
2661            let variant = wip.selected_variant();
2662            if let Some(v) = variant
2663                && v.data.kind != StructKind::Unit
2664                && !v.data.fields.is_empty()
2665            {
2666                return Err(DeserializeError::TypeMismatch {
2667                    expected: "content field for non-unit variant",
2668                    got: format!("missing '{content_key}' field"),
2669                });
2670            }
2671        }
2672
2673        Ok(wip)
2674    }
2675
2676    fn deserialize_enum_variant_content(
2677        &mut self,
2678        mut wip: Partial<'input, BORROW>,
2679    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2680        use facet_core::Characteristic;
2681
2682        // Get the selected variant's info
2683        let variant = wip
2684            .selected_variant()
2685            .ok_or_else(|| DeserializeError::TypeMismatch {
2686                expected: "selected variant",
2687                got: "no variant selected".into(),
2688            })?;
2689
2690        let variant_kind = variant.data.kind;
2691        let variant_fields = variant.data.fields;
2692
2693        match variant_kind {
2694            StructKind::Unit => {
2695                // Unit variant - normally nothing to deserialize
2696                // But some formats (like TOML with [VariantName]) might emit an empty struct
2697                // Check if there's a StructStart that we need to consume
2698                let event = self.expect_peek("value")?;
2699                if matches!(event, ParseEvent::StructStart(_)) {
2700                    self.expect_event("value")?; // consume StructStart
2701                    // Expect immediate StructEnd for empty struct
2702                    let end_event = self.expect_event("value")?;
2703                    if !matches!(end_event, ParseEvent::StructEnd) {
2704                        return Err(DeserializeError::TypeMismatch {
2705                            expected: "empty struct for unit variant",
2706                            got: format!("{end_event:?}"),
2707                        });
2708                    }
2709                }
2710                Ok(wip)
2711            }
2712            StructKind::Tuple | StructKind::TupleStruct => {
2713                if variant_fields.len() == 1 {
2714                    // Newtype variant - content is the single field's value
2715                    wip = wip.begin_nth_field(0).map_err(DeserializeError::reflect)?;
2716                    wip = self.deserialize_into(wip)?;
2717                    wip = wip.end().map_err(DeserializeError::reflect)?;
2718                } else {
2719                    // Multi-field tuple variant - expect array or struct (for XML/TOML with numeric keys)
2720                    let event = self.expect_event("value")?;
2721
2722                    // Accept SequenceStart (JSON arrays), ambiguous StructStart (XML elements),
2723                    // or Object StructStart (TOML/JSON with numeric keys like "0", "1")
2724                    let struct_mode = match event {
2725                        ParseEvent::SequenceStart(_) => false,
2726                        ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
2727                        // Accept objects with numeric keys as valid tuple representations
2728                        ParseEvent::StructStart(ContainerKind::Object) => true,
2729                        ParseEvent::StructStart(kind) => {
2730                            return Err(DeserializeError::TypeMismatch {
2731                                expected: "array",
2732                                got: kind.name().into(),
2733                            });
2734                        }
2735                        _ => {
2736                            return Err(DeserializeError::TypeMismatch {
2737                                expected: "sequence for tuple variant",
2738                                got: format!("{event:?}"),
2739                            });
2740                        }
2741                    };
2742
2743                    let mut idx = 0;
2744                    while idx < variant_fields.len() {
2745                        // In struct mode, skip FieldKey events
2746                        if struct_mode {
2747                            let event = self.expect_peek("value")?;
2748                            if matches!(event, ParseEvent::FieldKey(_)) {
2749                                self.expect_event("value")?;
2750                                continue;
2751                            }
2752                        }
2753
2754                        wip = wip
2755                            .begin_nth_field(idx)
2756                            .map_err(DeserializeError::reflect)?;
2757                        wip = self.deserialize_into(wip)?;
2758                        wip = wip.end().map_err(DeserializeError::reflect)?;
2759                        idx += 1;
2760                    }
2761
2762                    let event = self.expect_event("value")?;
2763                    if !matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
2764                        return Err(DeserializeError::TypeMismatch {
2765                            expected: "sequence end for tuple variant",
2766                            got: format!("{event:?}"),
2767                        });
2768                    }
2769                }
2770                Ok(wip)
2771            }
2772            StructKind::Struct => {
2773                // Struct variant - expect object with fields
2774                let event = self.expect_event("value")?;
2775                if !matches!(event, ParseEvent::StructStart(_)) {
2776                    return Err(DeserializeError::TypeMismatch {
2777                        expected: "struct for struct variant",
2778                        got: format!("{event:?}"),
2779                    });
2780                }
2781
2782                let num_fields = variant_fields.len();
2783                let mut fields_set = alloc::vec![false; num_fields];
2784                let mut ordered_field_index = 0usize;
2785
2786                loop {
2787                    let event = self.expect_event("value")?;
2788                    match event {
2789                        ParseEvent::StructEnd => break,
2790                        ParseEvent::OrderedField => {
2791                            // Non-self-describing formats emit OrderedField events in order
2792                            let idx = ordered_field_index;
2793                            ordered_field_index += 1;
2794                            if idx < num_fields {
2795                                wip = wip
2796                                    .begin_nth_field(idx)
2797                                    .map_err(DeserializeError::reflect)?;
2798                                wip = self.deserialize_into(wip)?;
2799                                wip = wip.end().map_err(DeserializeError::reflect)?;
2800                                fields_set[idx] = true;
2801                            }
2802                        }
2803                        ParseEvent::FieldKey(key) => {
2804                            // Uses namespace-aware matching when namespace is present
2805                            let field_info = variant_fields.iter().enumerate().find(|(_, f)| {
2806                                Self::field_matches_with_namespace(
2807                                    f,
2808                                    key.name.as_ref(),
2809                                    key.namespace.as_deref(),
2810                                    key.location,
2811                                    None, // Enums don't have ns_all
2812                                )
2813                            });
2814
2815                            if let Some((idx, _field)) = field_info {
2816                                wip = wip
2817                                    .begin_nth_field(idx)
2818                                    .map_err(DeserializeError::reflect)?;
2819                                wip = self.deserialize_into(wip)?;
2820                                wip = wip.end().map_err(DeserializeError::reflect)?;
2821                                fields_set[idx] = true;
2822                            } else {
2823                                // Unknown field - skip
2824                                self.parser.skip_value().map_err(DeserializeError::Parser)?;
2825                            }
2826                        }
2827                        other => {
2828                            return Err(DeserializeError::TypeMismatch {
2829                                expected: "field key, ordered field, or struct end",
2830                                got: format!("{other:?}"),
2831                            });
2832                        }
2833                    }
2834                }
2835
2836                // Apply defaults for missing fields
2837                for (idx, field) in variant_fields.iter().enumerate() {
2838                    if fields_set[idx] {
2839                        continue;
2840                    }
2841
2842                    let field_has_default = field.has_default();
2843                    let field_type_has_default = field.shape().is(Characteristic::Default);
2844                    let field_is_option = matches!(field.shape().def, Def::Option(_));
2845
2846                    if field_has_default || field_type_has_default {
2847                        wip = wip
2848                            .set_nth_field_to_default(idx)
2849                            .map_err(DeserializeError::reflect)?;
2850                    } else if field_is_option {
2851                        wip = wip
2852                            .begin_nth_field(idx)
2853                            .map_err(DeserializeError::reflect)?;
2854                        wip = wip.set_default().map_err(DeserializeError::reflect)?;
2855                        wip = wip.end().map_err(DeserializeError::reflect)?;
2856                    } else if field.should_skip_deserializing() {
2857                        wip = wip
2858                            .set_nth_field_to_default(idx)
2859                            .map_err(DeserializeError::reflect)?;
2860                    } else {
2861                        return Err(DeserializeError::TypeMismatch {
2862                            expected: "field to be present or have default",
2863                            got: format!("missing field '{}'", field.name),
2864                        });
2865                    }
2866                }
2867
2868                Ok(wip)
2869            }
2870        }
2871    }
2872
2873    fn deserialize_numeric_enum(
2874        &mut self,
2875        mut wip: Partial<'input, BORROW>,
2876    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2877        let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
2878
2879        if let Some(ParseEvent::Scalar(scalar)) = event {
2880            let span = self.last_span;
2881            wip = match scalar {
2882                ScalarValue::I64(discriminant) => wip
2883                    .select_variant(discriminant)
2884                    .map_err(|error| DeserializeError::Reflect { error, span })?,
2885                ScalarValue::U64(discriminant) => wip
2886                    .select_variant(discriminant as i64)
2887                    .map_err(|error| DeserializeError::Reflect { error, span })?,
2888                ScalarValue::Str(str_discriminant) => {
2889                    let discriminant =
2890                        str_discriminant
2891                            .parse()
2892                            .map_err(|_| DeserializeError::TypeMismatch {
2893                                expected: "String representing an integer (i64)",
2894                                got: str_discriminant.to_string(),
2895                            })?;
2896                    wip.select_variant(discriminant)
2897                        .map_err(|error| DeserializeError::Reflect { error, span })?
2898                }
2899                _ => {
2900                    return Err(DeserializeError::Unsupported(
2901                        "Unexpected ScalarValue".to_string(),
2902                    ));
2903                }
2904            };
2905            self.parser.next_event().map_err(DeserializeError::Parser)?;
2906            Ok(wip)
2907        } else {
2908            Err(DeserializeError::Unsupported(
2909                "Expected integer value".to_string(),
2910            ))
2911        }
2912    }
2913
2914    fn deserialize_enum_untagged(
2915        &mut self,
2916        mut wip: Partial<'input, BORROW>,
2917    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2918        use facet_solver::VariantsByFormat;
2919
2920        let shape = wip.shape();
2921        let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
2922            DeserializeError::Unsupported("expected enum type for untagged".into())
2923        })?;
2924
2925        let event = self.expect_peek("value")?;
2926
2927        match &event {
2928            ParseEvent::Scalar(scalar) => {
2929                // Try unit variants for null
2930                if matches!(scalar, ScalarValue::Null)
2931                    && let Some(variant) = variants_by_format.unit_variants.first()
2932                {
2933                    wip = wip
2934                        .select_variant_named(variant.name)
2935                        .map_err(DeserializeError::reflect)?;
2936                    // Consume the null
2937                    self.expect_event("value")?;
2938                    return Ok(wip);
2939                }
2940
2941                // Try unit variants for string values (match variant name)
2942                // This handles untagged enums with only unit variants like:
2943                // #[facet(untagged)] enum Color { Red, Green, Blue }
2944                // which deserialize from "Red", "Green", "Blue"
2945                if let ScalarValue::Str(s) = scalar {
2946                    for variant in &variants_by_format.unit_variants {
2947                        // Match against variant name or rename attribute
2948                        let variant_display_name = variant
2949                            .get_builtin_attr("rename")
2950                            .and_then(|attr| attr.get_as::<&str>().copied())
2951                            .unwrap_or(variant.name);
2952                        if s.as_ref() == variant_display_name {
2953                            wip = wip
2954                                .select_variant_named(variant.name)
2955                                .map_err(DeserializeError::reflect)?;
2956                            // Consume the string
2957                            self.expect_event("value")?;
2958                            return Ok(wip);
2959                        }
2960                    }
2961                }
2962
2963                // Try scalar variants
2964                // For untagged enums, we should try to deserialize each scalar variant in order.
2965                // This handles both primitive scalars (String, i32, etc.) and complex types that
2966                // can be deserialized from scalars (e.g., enums with #[facet(rename)]).
2967                //
2968                // Note: We can't easily back track parser state, so we only try the first variant
2969                // that matches. For proper untagged behavior with multiple possibilities, we'd need
2970                // to either:
2971                // 1. Implement parser checkpointing/backtracking
2972                // 2. Use a probe to determine which variant will succeed before attempting deserialization
2973                //
2974                // For now, we prioritize variants that match primitive scalars (fast path),
2975                // then try other scalar variants.
2976
2977                // First try variants that match primitive scalar types (fast path for String, i32, etc.)
2978                for (variant, inner_shape) in &variants_by_format.scalar_variants {
2979                    if self.scalar_matches_shape(scalar, inner_shape) {
2980                        wip = wip
2981                            .select_variant_named(variant.name)
2982                            .map_err(DeserializeError::reflect)?;
2983                        wip = self.deserialize_enum_variant_content(wip)?;
2984                        return Ok(wip);
2985                    }
2986                }
2987
2988                // Then try other scalar variants that don't match primitive types.
2989                // This handles cases like newtype variants wrapping enums with #[facet(rename)]:
2990                //   #[facet(untagged)]
2991                //   enum EditionOrWorkspace {
2992                //       Edition(Edition),  // Edition is an enum with #[facet(rename = "2024")]
2993                //       Workspace(WorkspaceRef),
2994                //   }
2995                // When deserializing "2024", Edition doesn't match as a primitive scalar,
2996                // but it CAN be deserialized from the string via its renamed unit variants.
2997                for (variant, inner_shape) in &variants_by_format.scalar_variants {
2998                    if !self.scalar_matches_shape(scalar, inner_shape) {
2999                        wip = wip
3000                            .select_variant_named(variant.name)
3001                            .map_err(DeserializeError::reflect)?;
3002                        // Try to deserialize - if this fails, it will bubble up as an error.
3003                        // TODO: Implement proper variant trying with backtracking for better error messages
3004                        wip = self.deserialize_enum_variant_content(wip)?;
3005                        return Ok(wip);
3006                    }
3007                }
3008
3009                Err(DeserializeError::TypeMismatch {
3010                    expected: "matching untagged variant for scalar",
3011                    got: format!("{:?}", scalar),
3012                })
3013            }
3014            ParseEvent::StructStart(_) => {
3015                // For struct input, use solve_variant for proper field-based matching
3016                match crate::solve_variant(shape, &mut self.parser) {
3017                    Ok(Some(outcome)) => {
3018                        // Successfully identified which variant matches based on fields
3019                        let resolution = outcome.resolution();
3020                        // For top-level untagged enum, there should be exactly one variant selection
3021                        let variant_name = resolution
3022                            .variant_selections()
3023                            .first()
3024                            .map(|vs| vs.variant_name)
3025                            .ok_or_else(|| {
3026                                DeserializeError::Unsupported(
3027                                    "solved resolution has no variant selection".into(),
3028                                )
3029                            })?;
3030                        wip = wip
3031                            .select_variant_named(variant_name)
3032                            .map_err(DeserializeError::reflect)?;
3033                        wip = self.deserialize_enum_variant_content(wip)?;
3034                        Ok(wip)
3035                    }
3036                    Ok(None) => {
3037                        // No variant matched - fall back to trying the first struct variant
3038                        // (we can't backtrack parser state to try multiple variants)
3039                        if let Some(variant) = variants_by_format.struct_variants.first() {
3040                            wip = wip
3041                                .select_variant_named(variant.name)
3042                                .map_err(DeserializeError::reflect)?;
3043                            wip = self.deserialize_enum_variant_content(wip)?;
3044                            Ok(wip)
3045                        } else {
3046                            Err(DeserializeError::Unsupported(
3047                                "no struct variant found for untagged enum with struct input"
3048                                    .into(),
3049                            ))
3050                        }
3051                    }
3052                    Err(_) => Err(DeserializeError::Unsupported(
3053                        "failed to solve variant for untagged enum".into(),
3054                    )),
3055                }
3056            }
3057            ParseEvent::SequenceStart(_) => {
3058                // For sequence input, use first tuple variant
3059                if let Some((variant, _arity)) = variants_by_format.tuple_variants.first() {
3060                    wip = wip
3061                        .select_variant_named(variant.name)
3062                        .map_err(DeserializeError::reflect)?;
3063                    wip = self.deserialize_enum_variant_content(wip)?;
3064                    return Ok(wip);
3065                }
3066
3067                Err(DeserializeError::Unsupported(
3068                    "no tuple variant found for untagged enum with sequence input".into(),
3069                ))
3070            }
3071            _ => Err(DeserializeError::TypeMismatch {
3072                expected: "scalar, struct, or sequence for untagged enum",
3073                got: format!("{:?}", event),
3074            }),
3075        }
3076    }
3077
3078    fn scalar_matches_shape(
3079        &self,
3080        scalar: &ScalarValue<'input>,
3081        shape: &'static facet_core::Shape,
3082    ) -> bool {
3083        use facet_core::ScalarType;
3084
3085        let Some(scalar_type) = shape.scalar_type() else {
3086            // Not a scalar type - check for Option wrapping null
3087            if matches!(scalar, ScalarValue::Null) {
3088                return matches!(shape.def, Def::Option(_));
3089            }
3090            return false;
3091        };
3092
3093        match scalar {
3094            ScalarValue::Bool(_) => matches!(scalar_type, ScalarType::Bool),
3095            ScalarValue::I64(val) => {
3096                // I64 matches signed types directly
3097                if matches!(
3098                    scalar_type,
3099                    ScalarType::I8
3100                        | ScalarType::I16
3101                        | ScalarType::I32
3102                        | ScalarType::I64
3103                        | ScalarType::I128
3104                        | ScalarType::ISize
3105                ) {
3106                    return true;
3107                }
3108
3109                // I64 can also match unsigned types if the value is non-negative and in range
3110                // This handles TOML's requirement to represent all integers as i64
3111                if *val >= 0 {
3112                    let uval = *val as u64;
3113                    match scalar_type {
3114                        ScalarType::U8 => uval <= u8::MAX as u64,
3115                        ScalarType::U16 => uval <= u16::MAX as u64,
3116                        ScalarType::U32 => uval <= u32::MAX as u64,
3117                        ScalarType::U64 | ScalarType::U128 | ScalarType::USize => true,
3118                        _ => false,
3119                    }
3120                } else {
3121                    false
3122                }
3123            }
3124            ScalarValue::U64(_) => matches!(
3125                scalar_type,
3126                ScalarType::U8
3127                    | ScalarType::U16
3128                    | ScalarType::U32
3129                    | ScalarType::U64
3130                    | ScalarType::U128
3131                    | ScalarType::USize
3132            ),
3133            ScalarValue::U128(_) => matches!(scalar_type, ScalarType::U128 | ScalarType::I128),
3134            ScalarValue::I128(_) => matches!(scalar_type, ScalarType::I128 | ScalarType::U128),
3135            ScalarValue::F64(_) => matches!(scalar_type, ScalarType::F32 | ScalarType::F64),
3136            ScalarValue::Str(_) => matches!(
3137                scalar_type,
3138                ScalarType::String | ScalarType::Str | ScalarType::CowStr | ScalarType::Char
3139            ),
3140            ScalarValue::Bytes(_) => {
3141                // Bytes don't have a ScalarType - would need to check for Vec<u8> or [u8]
3142                false
3143            }
3144            ScalarValue::Null => {
3145                // Null matches Unit type
3146                matches!(scalar_type, ScalarType::Unit)
3147            }
3148        }
3149    }
3150
3151    fn deserialize_list(
3152        &mut self,
3153        mut wip: Partial<'input, BORROW>,
3154    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3155        // Hint to non-self-describing parsers that a sequence is expected
3156        self.parser.hint_sequence();
3157
3158        let event = self.expect_event("value")?;
3159
3160        // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
3161        // In struct mode, we skip FieldKey events and treat values as sequence items
3162        // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
3163        let struct_mode = match event {
3164            ParseEvent::SequenceStart(_) => false,
3165            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
3166            ParseEvent::StructStart(kind) => {
3167                return Err(DeserializeError::TypeMismatch {
3168                    expected: "array",
3169                    got: kind.name().into(),
3170                });
3171            }
3172            _ => {
3173                return Err(DeserializeError::TypeMismatch {
3174                    expected: "sequence start",
3175                    got: format!("{event:?}"),
3176                });
3177            }
3178        };
3179
3180        // Initialize the list
3181        wip = wip.begin_list().map_err(DeserializeError::reflect)?;
3182
3183        loop {
3184            let event = self.expect_peek("value")?;
3185
3186            // Check for end of container
3187            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
3188                self.expect_event("value")?;
3189                break;
3190            }
3191
3192            // In struct mode, skip FieldKey events (they're just labels for items)
3193            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
3194                self.expect_event("value")?;
3195                continue;
3196            }
3197
3198            wip = wip.begin_list_item().map_err(DeserializeError::reflect)?;
3199            wip = self.deserialize_into(wip)?;
3200            wip = wip.end().map_err(DeserializeError::reflect)?;
3201        }
3202
3203        Ok(wip)
3204    }
3205
3206    fn deserialize_array(
3207        &mut self,
3208        mut wip: Partial<'input, BORROW>,
3209    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3210        // Get the fixed array length from the type definition
3211        let array_len = match &wip.shape().def {
3212            Def::Array(array_def) => array_def.n,
3213            _ => {
3214                return Err(DeserializeError::Unsupported(
3215                    "deserialize_array called on non-array type".into(),
3216                ));
3217            }
3218        };
3219
3220        // Hint to non-self-describing parsers that a fixed-size array is expected
3221        // (unlike hint_sequence, this doesn't read a length prefix)
3222        self.parser.hint_array(array_len);
3223
3224        let event = self.expect_event("value")?;
3225
3226        // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
3227        // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
3228        let struct_mode = match event {
3229            ParseEvent::SequenceStart(_) => false,
3230            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
3231            ParseEvent::StructStart(kind) => {
3232                return Err(DeserializeError::TypeMismatch {
3233                    expected: "array",
3234                    got: kind.name().into(),
3235                });
3236            }
3237            _ => {
3238                return Err(DeserializeError::TypeMismatch {
3239                    expected: "sequence start for array",
3240                    got: format!("{event:?}"),
3241                });
3242            }
3243        };
3244
3245        // Transition to Array tracker state. This is important for empty arrays
3246        // like [u8; 0] which have no elements to initialize but still need
3247        // their tracker state set correctly for require_full_initialization to pass.
3248        wip = wip.begin_array().map_err(DeserializeError::reflect)?;
3249
3250        let mut index = 0usize;
3251        loop {
3252            let event = self.expect_peek("value")?;
3253
3254            // Check for end of container
3255            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
3256                self.expect_event("value")?;
3257                break;
3258            }
3259
3260            // In struct mode, skip FieldKey events
3261            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
3262                self.expect_event("value")?;
3263                continue;
3264            }
3265
3266            wip = wip
3267                .begin_nth_field(index)
3268                .map_err(DeserializeError::reflect)?;
3269            wip = self.deserialize_into(wip)?;
3270            wip = wip.end().map_err(DeserializeError::reflect)?;
3271            index += 1;
3272        }
3273
3274        Ok(wip)
3275    }
3276
3277    fn deserialize_set(
3278        &mut self,
3279        mut wip: Partial<'input, BORROW>,
3280    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3281        // Hint to non-self-describing parsers that a sequence is expected
3282        self.parser.hint_sequence();
3283
3284        let event = self.expect_event("value")?;
3285
3286        // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
3287        // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
3288        let struct_mode = match event {
3289            ParseEvent::SequenceStart(_) => false,
3290            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
3291            ParseEvent::StructStart(kind) => {
3292                return Err(DeserializeError::TypeMismatch {
3293                    expected: "array",
3294                    got: kind.name().into(),
3295                });
3296            }
3297            _ => {
3298                return Err(DeserializeError::TypeMismatch {
3299                    expected: "sequence start for set",
3300                    got: format!("{event:?}"),
3301                });
3302            }
3303        };
3304
3305        // Initialize the set
3306        wip = wip.begin_set().map_err(DeserializeError::reflect)?;
3307
3308        loop {
3309            let event = self.expect_peek("value")?;
3310
3311            // Check for end of container
3312            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
3313                self.expect_event("value")?;
3314                break;
3315            }
3316
3317            // In struct mode, skip FieldKey events
3318            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
3319                self.expect_event("value")?;
3320                continue;
3321            }
3322
3323            wip = wip.begin_set_item().map_err(DeserializeError::reflect)?;
3324            wip = self.deserialize_into(wip)?;
3325            wip = wip.end().map_err(DeserializeError::reflect)?;
3326        }
3327
3328        Ok(wip)
3329    }
3330
3331    fn deserialize_map(
3332        &mut self,
3333        mut wip: Partial<'input, BORROW>,
3334    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3335        // For non-self-describing formats, hint that a map is expected
3336        self.parser.hint_map();
3337
3338        let event = self.expect_event("value")?;
3339
3340        // Initialize the map
3341        wip = wip.begin_map().map_err(DeserializeError::reflect)?;
3342
3343        // Handle both self-describing (StructStart) and non-self-describing (SequenceStart) formats
3344        match event {
3345            ParseEvent::StructStart(_) => {
3346                // Self-describing format (e.g., JSON): maps are represented as objects
3347                loop {
3348                    let event = self.expect_event("value")?;
3349                    match event {
3350                        ParseEvent::StructEnd => break,
3351                        ParseEvent::FieldKey(key) => {
3352                            // Begin key
3353                            wip = wip.begin_key().map_err(DeserializeError::reflect)?;
3354                            wip = self.deserialize_map_key(wip, key.name)?;
3355                            wip = wip.end().map_err(DeserializeError::reflect)?;
3356
3357                            // Begin value
3358                            wip = wip.begin_value().map_err(DeserializeError::reflect)?;
3359                            wip = self.deserialize_into(wip)?;
3360                            wip = wip.end().map_err(DeserializeError::reflect)?;
3361                        }
3362                        other => {
3363                            return Err(DeserializeError::TypeMismatch {
3364                                expected: "field key or struct end for map",
3365                                got: format!("{other:?}"),
3366                            });
3367                        }
3368                    }
3369                }
3370            }
3371            ParseEvent::SequenceStart(_) => {
3372                // Non-self-describing format (e.g., postcard): maps are sequences of key-value pairs
3373                loop {
3374                    let event = self.expect_peek("value")?;
3375                    match event {
3376                        ParseEvent::SequenceEnd => {
3377                            self.expect_event("value")?;
3378                            break;
3379                        }
3380                        ParseEvent::OrderedField => {
3381                            self.expect_event("value")?;
3382
3383                            // Deserialize key
3384                            wip = wip.begin_key().map_err(DeserializeError::reflect)?;
3385                            wip = self.deserialize_into(wip)?;
3386                            wip = wip.end().map_err(DeserializeError::reflect)?;
3387
3388                            // Deserialize value
3389                            wip = wip.begin_value().map_err(DeserializeError::reflect)?;
3390                            wip = self.deserialize_into(wip)?;
3391                            wip = wip.end().map_err(DeserializeError::reflect)?;
3392                        }
3393                        other => {
3394                            return Err(DeserializeError::TypeMismatch {
3395                                expected: "ordered field or sequence end for map",
3396                                got: format!("{other:?}"),
3397                            });
3398                        }
3399                    }
3400                }
3401            }
3402            other => {
3403                return Err(DeserializeError::TypeMismatch {
3404                    expected: "struct start or sequence start for map",
3405                    got: format!("{other:?}"),
3406                });
3407            }
3408        }
3409
3410        Ok(wip)
3411    }
3412
3413    fn deserialize_scalar(
3414        &mut self,
3415        mut wip: Partial<'input, BORROW>,
3416    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3417        // Hint to non-self-describing parsers what scalar type is expected
3418        let shape = wip.shape();
3419
3420        // First, try hint_opaque_scalar for types that may have format-specific
3421        // binary representations (e.g., UUID as 16 raw bytes in postcard)
3422        let opaque_handled = match shape.type_identifier {
3423            // Standard primitives are never opaque
3424            "bool" | "u8" | "u16" | "u32" | "u64" | "u128" | "usize" | "i8" | "i16" | "i32"
3425            | "i64" | "i128" | "isize" | "f32" | "f64" | "String" | "&str" | "char" => false,
3426            // For all other scalar types, ask the parser if it handles them specially
3427            _ => self.parser.hint_opaque_scalar(shape.type_identifier, shape),
3428        };
3429
3430        // If the parser didn't handle the opaque type, fall back to standard hints
3431        if !opaque_handled {
3432            let hint = match shape.type_identifier {
3433                "bool" => Some(ScalarTypeHint::Bool),
3434                "u8" => Some(ScalarTypeHint::U8),
3435                "u16" => Some(ScalarTypeHint::U16),
3436                "u32" => Some(ScalarTypeHint::U32),
3437                "u64" => Some(ScalarTypeHint::U64),
3438                "u128" => Some(ScalarTypeHint::U128),
3439                "usize" => Some(ScalarTypeHint::Usize),
3440                "i8" => Some(ScalarTypeHint::I8),
3441                "i16" => Some(ScalarTypeHint::I16),
3442                "i32" => Some(ScalarTypeHint::I32),
3443                "i64" => Some(ScalarTypeHint::I64),
3444                "i128" => Some(ScalarTypeHint::I128),
3445                "isize" => Some(ScalarTypeHint::Isize),
3446                "f32" => Some(ScalarTypeHint::F32),
3447                "f64" => Some(ScalarTypeHint::F64),
3448                "String" | "&str" => Some(ScalarTypeHint::String),
3449                "char" => Some(ScalarTypeHint::Char),
3450                // For unknown scalar types, check if they implement FromStr
3451                // (e.g., camino::Utf8PathBuf, types not handled by hint_opaque_scalar)
3452                _ if shape.is_from_str() => Some(ScalarTypeHint::String),
3453                _ => None,
3454            };
3455            if let Some(hint) = hint {
3456                self.parser.hint_scalar_type(hint);
3457            }
3458        }
3459
3460        let event = self.expect_event("value")?;
3461
3462        match event {
3463            ParseEvent::Scalar(scalar) => {
3464                wip = self.set_scalar(wip, scalar)?;
3465                Ok(wip)
3466            }
3467            other => Err(DeserializeError::TypeMismatch {
3468                expected: "scalar value",
3469                got: format!("{other:?}"),
3470            }),
3471        }
3472    }
3473
3474    fn set_scalar(
3475        &mut self,
3476        mut wip: Partial<'input, BORROW>,
3477        scalar: ScalarValue<'input>,
3478    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3479        let shape = wip.shape();
3480        // Capture the span for error reporting - this is where the scalar value was parsed
3481        let span = self.last_span;
3482        let reflect_err = |e: ReflectError| DeserializeError::Reflect { error: e, span };
3483
3484        match scalar {
3485            ScalarValue::Null => {
3486                wip = wip.set_default().map_err(&reflect_err)?;
3487            }
3488            ScalarValue::Bool(b) => {
3489                wip = wip.set(b).map_err(&reflect_err)?;
3490            }
3491            ScalarValue::I64(n) => {
3492                // Handle signed types
3493                if shape.type_identifier == "i8" {
3494                    wip = wip.set(n as i8).map_err(&reflect_err)?;
3495                } else if shape.type_identifier == "i16" {
3496                    wip = wip.set(n as i16).map_err(&reflect_err)?;
3497                } else if shape.type_identifier == "i32" {
3498                    wip = wip.set(n as i32).map_err(&reflect_err)?;
3499                } else if shape.type_identifier == "i64" {
3500                    wip = wip.set(n).map_err(&reflect_err)?;
3501                } else if shape.type_identifier == "i128" {
3502                    wip = wip.set(n as i128).map_err(&reflect_err)?;
3503                } else if shape.type_identifier == "isize" {
3504                    wip = wip.set(n as isize).map_err(&reflect_err)?;
3505                // Handle unsigned types (I64 can fit in unsigned if non-negative)
3506                } else if shape.type_identifier == "u8" {
3507                    wip = wip.set(n as u8).map_err(&reflect_err)?;
3508                } else if shape.type_identifier == "u16" {
3509                    wip = wip.set(n as u16).map_err(&reflect_err)?;
3510                } else if shape.type_identifier == "u32" {
3511                    wip = wip.set(n as u32).map_err(&reflect_err)?;
3512                } else if shape.type_identifier == "u64" {
3513                    wip = wip.set(n as u64).map_err(&reflect_err)?;
3514                } else if shape.type_identifier == "u128" {
3515                    wip = wip.set(n as u128).map_err(&reflect_err)?;
3516                } else if shape.type_identifier == "usize" {
3517                    wip = wip.set(n as usize).map_err(&reflect_err)?;
3518                // Handle floats
3519                } else if shape.type_identifier == "f32" {
3520                    wip = wip.set(n as f32).map_err(&reflect_err)?;
3521                } else if shape.type_identifier == "f64" {
3522                    wip = wip.set(n as f64).map_err(&reflect_err)?;
3523                // Handle String - stringify the number
3524                } else if shape.type_identifier == "String" {
3525                    wip = wip
3526                        .set(alloc::string::ToString::to_string(&n))
3527                        .map_err(&reflect_err)?;
3528                } else {
3529                    wip = wip.set(n).map_err(&reflect_err)?;
3530                }
3531            }
3532            ScalarValue::U64(n) => {
3533                // Handle unsigned types
3534                if shape.type_identifier == "u8" {
3535                    wip = wip.set(n as u8).map_err(&reflect_err)?;
3536                } else if shape.type_identifier == "u16" {
3537                    wip = wip.set(n as u16).map_err(&reflect_err)?;
3538                } else if shape.type_identifier == "u32" {
3539                    wip = wip.set(n as u32).map_err(&reflect_err)?;
3540                } else if shape.type_identifier == "u64" {
3541                    wip = wip.set(n).map_err(&reflect_err)?;
3542                } else if shape.type_identifier == "u128" {
3543                    wip = wip.set(n as u128).map_err(&reflect_err)?;
3544                } else if shape.type_identifier == "usize" {
3545                    wip = wip.set(n as usize).map_err(&reflect_err)?;
3546                // Handle signed types (U64 can fit in signed if small enough)
3547                } else if shape.type_identifier == "i8" {
3548                    wip = wip.set(n as i8).map_err(&reflect_err)?;
3549                } else if shape.type_identifier == "i16" {
3550                    wip = wip.set(n as i16).map_err(&reflect_err)?;
3551                } else if shape.type_identifier == "i32" {
3552                    wip = wip.set(n as i32).map_err(&reflect_err)?;
3553                } else if shape.type_identifier == "i64" {
3554                    wip = wip.set(n as i64).map_err(&reflect_err)?;
3555                } else if shape.type_identifier == "i128" {
3556                    wip = wip.set(n as i128).map_err(&reflect_err)?;
3557                } else if shape.type_identifier == "isize" {
3558                    wip = wip.set(n as isize).map_err(&reflect_err)?;
3559                // Handle floats
3560                } else if shape.type_identifier == "f32" {
3561                    wip = wip.set(n as f32).map_err(&reflect_err)?;
3562                } else if shape.type_identifier == "f64" {
3563                    wip = wip.set(n as f64).map_err(&reflect_err)?;
3564                // Handle String - stringify the number
3565                } else if shape.type_identifier == "String" {
3566                    wip = wip
3567                        .set(alloc::string::ToString::to_string(&n))
3568                        .map_err(&reflect_err)?;
3569                } else {
3570                    wip = wip.set(n).map_err(&reflect_err)?;
3571                }
3572            }
3573            ScalarValue::U128(n) => {
3574                // Handle u128 scalar
3575                if shape.type_identifier == "u128" {
3576                    wip = wip.set(n).map_err(&reflect_err)?;
3577                } else if shape.type_identifier == "i128" {
3578                    wip = wip.set(n as i128).map_err(&reflect_err)?;
3579                } else {
3580                    // For smaller types, truncate (caller should have used correct hint)
3581                    wip = wip.set(n as u64).map_err(&reflect_err)?;
3582                }
3583            }
3584            ScalarValue::I128(n) => {
3585                // Handle i128 scalar
3586                if shape.type_identifier == "i128" {
3587                    wip = wip.set(n).map_err(&reflect_err)?;
3588                } else if shape.type_identifier == "u128" {
3589                    wip = wip.set(n as u128).map_err(&reflect_err)?;
3590                } else {
3591                    // For smaller types, truncate (caller should have used correct hint)
3592                    wip = wip.set(n as i64).map_err(&reflect_err)?;
3593                }
3594            }
3595            ScalarValue::F64(n) => {
3596                if shape.type_identifier == "f32" {
3597                    wip = wip.set(n as f32).map_err(&reflect_err)?;
3598                } else if shape.type_identifier == "f64" {
3599                    wip = wip.set(n).map_err(&reflect_err)?;
3600                } else if shape.vtable.has_try_from() && shape.inner.is_some() {
3601                    // For opaque types with try_from (like NotNan, OrderedFloat), use
3602                    // begin_inner() + set + end() to trigger conversion
3603                    let inner_shape = shape.inner.unwrap();
3604                    wip = wip.begin_inner().map_err(&reflect_err)?;
3605                    if inner_shape.is_type::<f32>() {
3606                        wip = wip.set(n as f32).map_err(&reflect_err)?;
3607                    } else {
3608                        wip = wip.set(n).map_err(&reflect_err)?;
3609                    }
3610                    wip = wip.end().map_err(&reflect_err)?;
3611                } else {
3612                    wip = wip.set(n).map_err(&reflect_err)?;
3613                }
3614            }
3615            ScalarValue::Str(s) => {
3616                // Try parse_from_str first if the type supports it
3617                if shape.vtable.has_parse() {
3618                    wip = wip.parse_from_str(s.as_ref()).map_err(&reflect_err)?;
3619                } else {
3620                    wip = self.set_string_value(wip, s)?;
3621                }
3622            }
3623            ScalarValue::Bytes(b) => {
3624                // First try parse_from_bytes if the type supports it (e.g., UUID from 16 bytes)
3625                if shape.vtable.has_parse_bytes() {
3626                    wip = wip.parse_from_bytes(b.as_ref()).map_err(&reflect_err)?;
3627                } else {
3628                    // Fall back to setting as Vec<u8>
3629                    wip = wip.set(b.into_owned()).map_err(&reflect_err)?;
3630                }
3631            }
3632        }
3633
3634        Ok(wip)
3635    }
3636
3637    /// Set a string value, handling `&str`, `Cow<str>`, and `String` appropriately.
3638    fn set_string_value(
3639        &mut self,
3640        mut wip: Partial<'input, BORROW>,
3641        s: Cow<'input, str>,
3642    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3643        let shape = wip.shape();
3644
3645        // Check if target is &str (shared reference to str)
3646        if let Def::Pointer(ptr_def) = shape.def
3647            && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
3648            && ptr_def
3649                .pointee()
3650                .is_some_and(|p| p.type_identifier == "str")
3651        {
3652            // In owned mode, we cannot borrow from input at all
3653            if !BORROW {
3654                return Err(DeserializeError::CannotBorrow {
3655                    message: "cannot deserialize into &str when borrowing is disabled - use String or Cow<str> instead".into(),
3656                });
3657            }
3658            match s {
3659                Cow::Borrowed(borrowed) => {
3660                    wip = wip.set(borrowed).map_err(DeserializeError::reflect)?;
3661                    return Ok(wip);
3662                }
3663                Cow::Owned(_) => {
3664                    return Err(DeserializeError::CannotBorrow {
3665                        message: "cannot borrow &str from string containing escape sequences - use String or Cow<str> instead".into(),
3666                    });
3667                }
3668            }
3669        }
3670
3671        // Check if target is Cow<str>
3672        if let Def::Pointer(ptr_def) = shape.def
3673            && matches!(ptr_def.known, Some(KnownPointer::Cow))
3674            && ptr_def
3675                .pointee()
3676                .is_some_and(|p| p.type_identifier == "str")
3677        {
3678            wip = wip.set(s).map_err(DeserializeError::reflect)?;
3679            return Ok(wip);
3680        }
3681
3682        // Default: convert to owned String
3683        wip = wip.set(s.into_owned()).map_err(DeserializeError::reflect)?;
3684        Ok(wip)
3685    }
3686
3687    /// Set a bytes value with proper handling for borrowed vs owned data.
3688    ///
3689    /// This handles `&[u8]`, `Cow<[u8]>`, and `Vec<u8>` appropriately based on
3690    /// whether borrowing is enabled and whether the data is borrowed or owned.
3691    fn set_bytes_value(
3692        &mut self,
3693        mut wip: Partial<'input, BORROW>,
3694        b: Cow<'input, [u8]>,
3695    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3696        let shape = wip.shape();
3697
3698        // Helper to check if a shape is a byte slice ([u8])
3699        let is_byte_slice = |pointee: &facet_core::Shape| matches!(pointee.def, Def::Slice(slice_def) if slice_def.t.type_identifier == "u8");
3700
3701        // Check if target is &[u8] (shared reference to byte slice)
3702        if let Def::Pointer(ptr_def) = shape.def
3703            && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
3704            && ptr_def.pointee().is_some_and(is_byte_slice)
3705        {
3706            // In owned mode, we cannot borrow from input at all
3707            if !BORROW {
3708                return Err(DeserializeError::CannotBorrow {
3709                    message: "cannot deserialize into &[u8] when borrowing is disabled - use Vec<u8> or Cow<[u8]> instead".into(),
3710                });
3711            }
3712            match b {
3713                Cow::Borrowed(borrowed) => {
3714                    wip = wip.set(borrowed).map_err(DeserializeError::reflect)?;
3715                    return Ok(wip);
3716                }
3717                Cow::Owned(_) => {
3718                    return Err(DeserializeError::CannotBorrow {
3719                        message: "cannot borrow &[u8] from owned bytes - use Vec<u8> or Cow<[u8]> instead".into(),
3720                    });
3721                }
3722            }
3723        }
3724
3725        // Check if target is Cow<[u8]>
3726        if let Def::Pointer(ptr_def) = shape.def
3727            && matches!(ptr_def.known, Some(KnownPointer::Cow))
3728            && ptr_def.pointee().is_some_and(is_byte_slice)
3729        {
3730            wip = wip.set(b).map_err(DeserializeError::reflect)?;
3731            return Ok(wip);
3732        }
3733
3734        // Default: convert to owned Vec<u8>
3735        wip = wip.set(b.into_owned()).map_err(DeserializeError::reflect)?;
3736        Ok(wip)
3737    }
3738
3739    /// Deserialize a map key from a string.
3740    ///
3741    /// Format parsers typically emit string keys, but the target map might have non-string key types
3742    /// (e.g., integers, enums). This function parses the string key into the appropriate type:
3743    /// - String types: set directly
3744    /// - Enum unit variants: use select_variant_named
3745    /// - Integer types: parse the string as a number
3746    /// - Transparent newtypes: descend into the inner type
3747    fn deserialize_map_key(
3748        &mut self,
3749        mut wip: Partial<'input, BORROW>,
3750        key: Cow<'input, str>,
3751    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3752        let shape = wip.shape();
3753
3754        // For transparent types (like UserId(String)), we need to use begin_inner
3755        // to set the inner value. But NOT for pointer types like &str or Cow<str>
3756        // which are handled directly.
3757        let is_pointer = matches!(shape.def, Def::Pointer(_));
3758        if shape.inner.is_some() && !is_pointer {
3759            wip = wip.begin_inner().map_err(DeserializeError::reflect)?;
3760            wip = self.deserialize_map_key(wip, key)?;
3761            wip = wip.end().map_err(DeserializeError::reflect)?;
3762            return Ok(wip);
3763        }
3764
3765        // Check if target is an enum - use select_variant_named for unit variants
3766        if let Type::User(UserType::Enum(_)) = &shape.ty {
3767            wip = wip
3768                .select_variant_named(&key)
3769                .map_err(DeserializeError::reflect)?;
3770            return Ok(wip);
3771        }
3772
3773        // Check if target is a numeric type - parse the string key as a number
3774        if let Type::Primitive(PrimitiveType::Numeric(num_ty)) = &shape.ty {
3775            match num_ty {
3776                NumericType::Integer { signed } => {
3777                    if *signed {
3778                        let n: i64 = key.parse().map_err(|_| DeserializeError::TypeMismatch {
3779                            expected: "valid integer for map key",
3780                            got: format!("string '{}'", key),
3781                        })?;
3782                        // Use set for each size - the Partial handles type conversion
3783                        wip = wip.set(n).map_err(DeserializeError::reflect)?;
3784                    } else {
3785                        let n: u64 = key.parse().map_err(|_| DeserializeError::TypeMismatch {
3786                            expected: "valid unsigned integer for map key",
3787                            got: format!("string '{}'", key),
3788                        })?;
3789                        wip = wip.set(n).map_err(DeserializeError::reflect)?;
3790                    }
3791                    return Ok(wip);
3792                }
3793                NumericType::Float => {
3794                    let n: f64 = key.parse().map_err(|_| DeserializeError::TypeMismatch {
3795                        expected: "valid float for map key",
3796                        got: format!("string '{}'", key),
3797                    })?;
3798                    wip = wip.set(n).map_err(DeserializeError::reflect)?;
3799                    return Ok(wip);
3800                }
3801            }
3802        }
3803
3804        // Default: treat as string
3805        wip = self.set_string_value(wip, key)?;
3806        Ok(wip)
3807    }
3808
3809    /// Deserialize any value into a DynamicValue type (e.g., facet_value::Value).
3810    ///
3811    /// This handles all value types by inspecting the parse events and calling
3812    /// the appropriate methods on the Partial, which delegates to the DynamicValue vtable.
3813    fn deserialize_dynamic_value(
3814        &mut self,
3815        mut wip: Partial<'input, BORROW>,
3816    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
3817        let event = self.expect_peek("value for dynamic value")?;
3818
3819        match event {
3820            ParseEvent::Scalar(_) => {
3821                // Consume the scalar
3822                let event = self.expect_event("scalar")?;
3823                if let ParseEvent::Scalar(scalar) = event {
3824                    // Use set_scalar which already handles all scalar types
3825                    wip = self.set_scalar(wip, scalar)?;
3826                }
3827            }
3828            ParseEvent::SequenceStart(_) => {
3829                // Array/list
3830                self.expect_event("sequence start")?; // consume '['
3831                wip = wip.begin_list().map_err(DeserializeError::reflect)?;
3832
3833                loop {
3834                    let event = self.expect_peek("value or end")?;
3835                    if matches!(event, ParseEvent::SequenceEnd) {
3836                        self.expect_event("sequence end")?;
3837                        break;
3838                    }
3839
3840                    wip = wip.begin_list_item().map_err(DeserializeError::reflect)?;
3841                    wip = self.deserialize_dynamic_value(wip)?;
3842                    wip = wip.end().map_err(DeserializeError::reflect)?;
3843                }
3844            }
3845            ParseEvent::StructStart(_) => {
3846                // Object/map/table
3847                self.expect_event("struct start")?; // consume '{'
3848                wip = wip.begin_map().map_err(DeserializeError::reflect)?;
3849
3850                loop {
3851                    let event = self.expect_peek("field key or end")?;
3852                    if matches!(event, ParseEvent::StructEnd) {
3853                        self.expect_event("struct end")?;
3854                        break;
3855                    }
3856
3857                    // Parse the key
3858                    let key_event = self.expect_event("field key")?;
3859                    let key = match key_event {
3860                        ParseEvent::FieldKey(field_key) => field_key.name.into_owned(),
3861                        _ => {
3862                            return Err(DeserializeError::TypeMismatch {
3863                                expected: "field key",
3864                                got: format!("{:?}", key_event),
3865                            });
3866                        }
3867                    };
3868
3869                    // Begin the object entry and deserialize the value
3870                    wip = wip
3871                        .begin_object_entry(&key)
3872                        .map_err(DeserializeError::reflect)?;
3873                    wip = self.deserialize_dynamic_value(wip)?;
3874                    wip = wip.end().map_err(DeserializeError::reflect)?;
3875                }
3876            }
3877            _ => {
3878                return Err(DeserializeError::TypeMismatch {
3879                    expected: "scalar, sequence, or struct",
3880                    got: format!("{:?}", event),
3881                });
3882            }
3883        }
3884
3885        Ok(wip)
3886    }
3887}
3888
3889/// Error produced by [`FormatDeserializer`].
3890#[derive(Debug)]
3891pub enum DeserializeError<E> {
3892    /// Error emitted by the format-specific parser.
3893    Parser(E),
3894    /// Reflection error from Partial operations.
3895    Reflect {
3896        /// The underlying reflection error.
3897        error: ReflectError,
3898        /// Source span where the error occurred (if available).
3899        span: Option<facet_reflect::Span>,
3900    },
3901    /// Type mismatch during deserialization.
3902    TypeMismatch {
3903        /// The expected type or token.
3904        expected: &'static str,
3905        /// The actual type or token that was encountered.
3906        got: String,
3907    },
3908    /// Unsupported type or operation.
3909    Unsupported(String),
3910    /// Unknown field encountered when deny_unknown_fields is set.
3911    UnknownField(String),
3912    /// Cannot borrow string from input (e.g., escaped string into &str).
3913    CannotBorrow {
3914        /// Description of why borrowing failed.
3915        message: String,
3916    },
3917    /// Required field missing from input.
3918    MissingField {
3919        /// The field that is missing.
3920        field: &'static str,
3921        /// The type that contains the field.
3922        type_name: &'static str,
3923    },
3924    /// Unexpected end of input.
3925    UnexpectedEof {
3926        /// What was expected before EOF.
3927        expected: &'static str,
3928    },
3929}
3930
3931impl<E: fmt::Display> fmt::Display for DeserializeError<E> {
3932    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3933        match self {
3934            DeserializeError::Parser(err) => write!(f, "{err}"),
3935            DeserializeError::Reflect { error, .. } => write!(f, "reflection error: {error}"),
3936            DeserializeError::TypeMismatch { expected, got } => {
3937                write!(f, "type mismatch: expected {expected}, got {got}")
3938            }
3939            DeserializeError::Unsupported(msg) => write!(f, "unsupported: {msg}"),
3940            DeserializeError::UnknownField(field) => write!(f, "unknown field: {field}"),
3941            DeserializeError::CannotBorrow { message } => write!(f, "{message}"),
3942            DeserializeError::MissingField { field, type_name } => {
3943                write!(f, "missing field `{field}` in type `{type_name}`")
3944            }
3945            DeserializeError::UnexpectedEof { expected } => {
3946                write!(f, "unexpected end of input, expected {expected}")
3947            }
3948        }
3949    }
3950}
3951
3952impl<E: fmt::Debug + fmt::Display> std::error::Error for DeserializeError<E> {}
3953
3954impl<E> DeserializeError<E> {
3955    /// Create a Reflect error without span information.
3956    #[inline]
3957    pub fn reflect(error: ReflectError) -> Self {
3958        DeserializeError::Reflect { error, span: None }
3959    }
3960
3961    /// Create a Reflect error with span information.
3962    #[inline]
3963    pub fn reflect_with_span(error: ReflectError, span: facet_reflect::Span) -> Self {
3964        DeserializeError::Reflect {
3965            error,
3966            span: Some(span),
3967        }
3968    }
3969}