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