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::{Def, Facet, KnownPointer, StructKind, Type, UserType};
9use facet_reflect::{HeapValue, Partial, ReflectError};
10
11use crate::{FieldLocationHint, FormatParser, ParseEvent, ScalarValue};
12
13/// Generic deserializer that drives a format-specific parser directly into `Partial`.
14///
15/// The const generic `BORROW` controls whether string data can be borrowed:
16/// - `BORROW=true`: strings without escapes are borrowed from input
17/// - `BORROW=false`: all strings are owned
18pub struct FormatDeserializer<'input, const BORROW: bool, P> {
19    parser: P,
20    _marker: core::marker::PhantomData<&'input ()>,
21}
22
23impl<'input, P> FormatDeserializer<'input, true, P> {
24    /// Create a new deserializer that can borrow strings from input.
25    pub const fn new(parser: P) -> Self {
26        Self {
27            parser,
28            _marker: core::marker::PhantomData,
29        }
30    }
31}
32
33impl<'input, P> FormatDeserializer<'input, false, P> {
34    /// Create a new deserializer that produces owned strings.
35    pub const fn new_owned(parser: P) -> Self {
36        Self {
37            parser,
38            _marker: core::marker::PhantomData,
39        }
40    }
41}
42
43impl<'input, const BORROW: bool, P> FormatDeserializer<'input, BORROW, P> {
44    /// Consume the facade and return the underlying parser.
45    pub fn into_inner(self) -> P {
46        self.parser
47    }
48
49    /// Borrow the inner parser mutably.
50    pub fn parser_mut(&mut self) -> &mut P {
51        &mut self.parser
52    }
53}
54
55impl<'input, P> FormatDeserializer<'input, true, P>
56where
57    P: FormatParser<'input>,
58{
59    /// Deserialize the next value in the stream into `T`, allowing borrowed strings.
60    pub fn deserialize<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
61    where
62        T: Facet<'input>,
63    {
64        let wip: Partial<'input, true> =
65            Partial::alloc::<T>().map_err(DeserializeError::Reflect)?;
66        let partial = self.deserialize_into(wip)?;
67        let heap_value: HeapValue<'input, true> =
68            partial.build().map_err(DeserializeError::Reflect)?;
69        heap_value
70            .materialize::<T>()
71            .map_err(DeserializeError::Reflect)
72    }
73
74    /// Deserialize the next value in the stream into `T` (for backward compatibility).
75    pub fn deserialize_root<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
76    where
77        T: Facet<'input>,
78    {
79        self.deserialize()
80    }
81}
82
83impl<'input, P> FormatDeserializer<'input, false, P>
84where
85    P: FormatParser<'input>,
86{
87    /// Deserialize the next value in the stream into `T`, using owned strings.
88    pub fn deserialize<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
89    where
90        T: Facet<'static>,
91    {
92        // SAFETY: alloc_owned produces Partial<'static, false>, but our deserializer
93        // expects 'input. Since BORROW=false means we never borrow from input anyway,
94        // this is safe. We also transmute the HeapValue back to 'static before materializing.
95        #[allow(unsafe_code)]
96        let wip: Partial<'input, false> = unsafe {
97            core::mem::transmute::<Partial<'static, false>, Partial<'input, false>>(
98                Partial::alloc_owned::<T>().map_err(DeserializeError::Reflect)?,
99            )
100        };
101        let partial = self.deserialize_into(wip)?;
102        let heap_value: HeapValue<'input, false> =
103            partial.build().map_err(DeserializeError::Reflect)?;
104
105        // SAFETY: HeapValue<'input, false> contains no borrowed data because BORROW=false.
106        // The transmute only changes the phantom lifetime marker.
107        #[allow(unsafe_code)]
108        let heap_value: HeapValue<'static, false> = unsafe {
109            core::mem::transmute::<HeapValue<'input, false>, HeapValue<'static, false>>(heap_value)
110        };
111
112        heap_value
113            .materialize::<T>()
114            .map_err(DeserializeError::Reflect)
115    }
116
117    /// Deserialize the next value in the stream into `T` (for backward compatibility).
118    pub fn deserialize_root<T>(&mut self) -> Result<T, DeserializeError<P::Error>>
119    where
120        T: Facet<'static>,
121    {
122        self.deserialize()
123    }
124}
125
126impl<'input, const BORROW: bool, P> FormatDeserializer<'input, BORROW, P>
127where
128    P: FormatParser<'input>,
129{
130    /// Main deserialization entry point - deserialize into a Partial.
131    pub fn deserialize_into(
132        &mut self,
133        mut wip: Partial<'input, BORROW>,
134    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
135        let shape = wip.shape();
136
137        // Check for raw capture type (e.g., RawJson)
138        // Raw capture types are tuple structs with a single Cow<str> field
139        // If capture_raw returns None (e.g., streaming mode), fall through
140        // and try normal deserialization (which will likely fail with a helpful error)
141        if self.parser.raw_capture_shape() == Some(shape)
142            && let Some(raw) = self
143                .parser
144                .capture_raw()
145                .map_err(DeserializeError::Parser)?
146        {
147            // The raw type is a tuple struct like RawJson(Cow<str>)
148            // Access field 0 (the Cow<str>) and set it
149            wip = wip.begin_nth_field(0).map_err(DeserializeError::Reflect)?;
150            wip = self.set_string_value(wip, Cow::Borrowed(raw))?;
151            wip = wip.end().map_err(DeserializeError::Reflect)?;
152            return Ok(wip);
153        }
154
155        // Check for container-level proxy
156        let (wip_returned, has_proxy) = wip
157            .begin_custom_deserialization_from_shape()
158            .map_err(DeserializeError::Reflect)?;
159        wip = wip_returned;
160        if has_proxy {
161            wip = self.deserialize_into(wip)?;
162            return wip.end().map_err(DeserializeError::Reflect);
163        }
164
165        // Check for field-level proxy (opaque types with proxy attribute)
166        if wip
167            .parent_field()
168            .and_then(|field| field.proxy_convert_in_fn())
169            .is_some()
170        {
171            wip = wip
172                .begin_custom_deserialization()
173                .map_err(DeserializeError::Reflect)?;
174            wip = self.deserialize_into(wip)?;
175            wip = wip.end().map_err(DeserializeError::Reflect)?;
176            return Ok(wip);
177        }
178
179        // Check Def first for Option
180        if matches!(&shape.def, Def::Option(_)) {
181            return self.deserialize_option(wip);
182        }
183
184        // Priority 1: Check for builder_shape (immutable collections like Bytes -> BytesMut)
185        if shape.builder_shape.is_some() {
186            wip = wip.begin_inner().map_err(DeserializeError::Reflect)?;
187            wip = self.deserialize_into(wip)?;
188            wip = wip.end().map_err(DeserializeError::Reflect)?;
189            return Ok(wip);
190        }
191
192        // Priority 2: Check for smart pointers (Box, Arc, Rc)
193        if matches!(&shape.def, Def::Pointer(_)) {
194            return self.deserialize_pointer(wip);
195        }
196
197        // Priority 3: Check for .inner (transparent wrappers like NonZero)
198        // Collections (List/Map/Set/Array) have .inner for variance but shouldn't use this path
199        if shape.inner.is_some()
200            && !matches!(
201                &shape.def,
202                Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
203            )
204        {
205            wip = wip.begin_inner().map_err(DeserializeError::Reflect)?;
206            wip = self.deserialize_into(wip)?;
207            wip = wip.end().map_err(DeserializeError::Reflect)?;
208            return Ok(wip);
209        }
210
211        // Priority 4: Check the Type for structs and enums
212        match &shape.ty {
213            Type::User(UserType::Struct(struct_def)) => {
214                if matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct) {
215                    return self.deserialize_tuple(wip);
216                }
217                return self.deserialize_struct(wip);
218            }
219            Type::User(UserType::Enum(_)) => return self.deserialize_enum(wip),
220            _ => {}
221        }
222
223        // Priority 5: Check Def for containers and scalars
224        match &shape.def {
225            Def::Scalar => self.deserialize_scalar(wip),
226            Def::List(_) => self.deserialize_list(wip),
227            Def::Map(_) => self.deserialize_map(wip),
228            Def::Array(_) => self.deserialize_array(wip),
229            Def::Set(_) => self.deserialize_set(wip),
230            _ => Err(DeserializeError::Unsupported(format!(
231                "unsupported shape def: {:?}",
232                shape.def
233            ))),
234        }
235    }
236
237    fn deserialize_option(
238        &mut self,
239        mut wip: Partial<'input, BORROW>,
240    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
241        let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
242
243        if matches!(event, ParseEvent::Scalar(ScalarValue::Null)) {
244            // Consume the null
245            self.parser.next_event().map_err(DeserializeError::Parser)?;
246            // Set to None (default)
247            wip = wip.set_default().map_err(DeserializeError::Reflect)?;
248        } else {
249            // Some(value)
250            wip = wip.begin_some().map_err(DeserializeError::Reflect)?;
251            wip = self.deserialize_into(wip)?;
252            wip = wip.end().map_err(DeserializeError::Reflect)?;
253        }
254        Ok(wip)
255    }
256
257    fn deserialize_pointer(
258        &mut self,
259        mut wip: Partial<'input, BORROW>,
260    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
261        use facet_core::KnownPointer;
262
263        let shape = wip.shape();
264        let is_cow = if let Def::Pointer(ptr_def) = shape.def {
265            matches!(ptr_def.known, Some(KnownPointer::Cow))
266        } else {
267            false
268        };
269
270        if is_cow {
271            // Cow<str> - handle specially to preserve borrowing
272            if let Def::Pointer(ptr_def) = shape.def
273                && let Some(pointee) = ptr_def.pointee()
274                && pointee.type_identifier == "str"
275            {
276                let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
277                if let ParseEvent::Scalar(ScalarValue::Str(s)) = event {
278                    // Pass through the Cow as-is to preserve borrowing
279                    wip = wip.set(s).map_err(DeserializeError::Reflect)?;
280                    return Ok(wip);
281                } else {
282                    return Err(DeserializeError::TypeMismatch {
283                        expected: "string for Cow<str>",
284                        got: format!("{event:?}"),
285                    });
286                }
287            }
288            // Other Cow types - use begin_inner
289            wip = wip.begin_inner().map_err(DeserializeError::Reflect)?;
290            wip = self.deserialize_into(wip)?;
291            wip = wip.end().map_err(DeserializeError::Reflect)?;
292            return Ok(wip);
293        }
294
295        // &str - handle specially for zero-copy borrowing
296        if let Def::Pointer(ptr_def) = shape.def
297            && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
298            && ptr_def
299                .pointee()
300                .is_some_and(|p| p.type_identifier == "str")
301        {
302            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
303            if let ParseEvent::Scalar(ScalarValue::Str(s)) = event {
304                return self.set_string_value(wip, s);
305            } else {
306                return Err(DeserializeError::TypeMismatch {
307                    expected: "string for &str",
308                    got: format!("{event:?}"),
309                });
310            }
311        }
312
313        // Regular smart pointer (Box, Arc, Rc)
314        wip = wip.begin_smart_ptr().map_err(DeserializeError::Reflect)?;
315
316        // Check if begin_smart_ptr set up a slice builder (for Arc<[T]>, Rc<[T]>, Box<[T]>)
317        // In this case, we need to deserialize as a list manually
318        let is_slice_builder = wip.is_building_smart_ptr_slice();
319
320        if is_slice_builder {
321            // Deserialize the list elements into the slice builder
322            // We can't use deserialize_list() because it calls begin_list() which interferes
323            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
324
325            // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
326            // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
327            let struct_mode = match event {
328                ParseEvent::SequenceStart(_) => false,
329                ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
330                ParseEvent::StructStart(kind) => {
331                    return Err(DeserializeError::TypeMismatch {
332                        expected: "array",
333                        got: kind.name().into(),
334                    });
335                }
336                _ => {
337                    return Err(DeserializeError::TypeMismatch {
338                        expected: "sequence start for Arc<[T]>/Rc<[T]>/Box<[T]>",
339                        got: format!("{event:?}"),
340                    });
341                }
342            };
343
344            loop {
345                let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
346
347                // Check for end of container
348                if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
349                    self.parser.next_event().map_err(DeserializeError::Parser)?;
350                    break;
351                }
352
353                // In struct mode, skip FieldKey events
354                if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
355                    self.parser.next_event().map_err(DeserializeError::Parser)?;
356                    continue;
357                }
358
359                wip = wip.begin_list_item().map_err(DeserializeError::Reflect)?;
360                wip = self.deserialize_into(wip)?;
361                wip = wip.end().map_err(DeserializeError::Reflect)?;
362            }
363
364            // Convert the slice builder to Arc/Rc/Box and mark as initialized
365            wip = wip.end().map_err(DeserializeError::Reflect)?;
366            // DON'T call end() again - the caller (deserialize_struct) will do that
367        } else {
368            // Regular smart pointer with sized pointee
369            wip = self.deserialize_into(wip)?;
370            wip = wip.end().map_err(DeserializeError::Reflect)?;
371        }
372
373        Ok(wip)
374    }
375
376    /// Check if a field matches the given name and namespace constraints.
377    ///
378    /// This implements namespace-aware field matching for XML:
379    /// - Attributes: Only match if explicit xml::ns matches (no ns_all inheritance per XML spec)
380    /// - Elements: Match if explicit xml::ns OR ns_all matches
381    /// - No constraint: Backwards compatible - match any namespace by name only
382    fn field_matches_with_namespace(
383        field: &facet_core::Field,
384        name: &str,
385        namespace: Option<&str>,
386        location: FieldLocationHint,
387        ns_all: Option<&str>,
388    ) -> bool {
389        // Check name/alias
390        let name_matches = field.name == name || field.alias.iter().any(|alias| *alias == name);
391
392        if !name_matches {
393            return false;
394        }
395
396        // Get the expected namespace for this field
397        let field_xml_ns = field
398            .get_attr(Some("xml"), "ns")
399            .and_then(|attr| attr.get_as::<&str>().copied());
400
401        // CRITICAL: Attributes don't inherit ns_all (per XML spec)
402        let expected_ns = if matches!(location, FieldLocationHint::Attribute) {
403            field_xml_ns // Attributes: only explicit xml::ns
404        } else {
405            field_xml_ns.or(ns_all) // Elements: xml::ns OR ns_all
406        };
407
408        // Check if namespaces match
409        match (namespace, expected_ns) {
410            (Some(input_ns), Some(expected)) => input_ns == expected,
411            (Some(_input_ns), None) => true, // Input has namespace, field doesn't require one - match
412            (None, Some(_expected)) => false, // Input has no namespace, field requires one - NO match
413            (None, None) => true,             // Neither has namespace - match
414        }
415    }
416
417    fn deserialize_struct(
418        &mut self,
419        wip: Partial<'input, BORROW>,
420    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
421        // Get struct fields for lookup
422        let struct_def = match &wip.shape().ty {
423            Type::User(UserType::Struct(def)) => def,
424            _ => {
425                return Err(DeserializeError::Unsupported(format!(
426                    "expected struct type but got {:?}",
427                    wip.shape().ty
428                )));
429            }
430        };
431
432        // Check if we have any flattened fields
433        let has_flatten = struct_def.fields.iter().any(|f| f.is_flattened());
434
435        if has_flatten {
436            // Check if any flatten field is an enum (requires solver)
437            // or if there's nested flatten (flatten inside flatten)
438            let needs_solver = struct_def.fields.iter().any(|f| {
439                if !f.is_flattened() {
440                    return false;
441                }
442                // Get inner type, unwrapping Option if present
443                let inner_shape = match f.shape().def {
444                    Def::Option(opt) => opt.t,
445                    _ => f.shape(),
446                };
447                match inner_shape.ty {
448                    // Enum flatten needs solver
449                    Type::User(UserType::Enum(_)) => true,
450                    // Check for nested flatten (flatten field has its own flatten fields)
451                    Type::User(UserType::Struct(inner_struct)) => inner_struct
452                        .fields
453                        .iter()
454                        .any(|inner_f| inner_f.is_flattened()),
455                    _ => false,
456                }
457            });
458
459            if needs_solver {
460                self.deserialize_struct_with_flatten(wip)
461            } else {
462                // Simple single-level flatten - use the original approach
463                self.deserialize_struct_single_flatten(wip)
464            }
465        } else {
466            self.deserialize_struct_simple(wip)
467        }
468    }
469
470    /// Deserialize a struct without flattened fields (simple case).
471    fn deserialize_struct_simple(
472        &mut self,
473        mut wip: Partial<'input, BORROW>,
474    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
475        use facet_core::Characteristic;
476
477        // Expect StructStart
478        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
479        if !matches!(event, ParseEvent::StructStart(_)) {
480            return Err(DeserializeError::TypeMismatch {
481                expected: "struct start",
482                got: format!("{event:?}"),
483            });
484        }
485
486        // Get struct fields for lookup
487        let struct_def = match &wip.shape().ty {
488            Type::User(UserType::Struct(def)) => def,
489            _ => {
490                return Err(DeserializeError::Unsupported(format!(
491                    "expected struct type but got {:?}",
492                    wip.shape().ty
493                )));
494            }
495        };
496
497        let struct_has_default = wip.shape().has_default_attr();
498        let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
499
500        // Extract container-level default namespace (xml::ns_all) for namespace-aware matching
501        let ns_all = wip
502            .shape()
503            .attributes
504            .iter()
505            .find(|attr| attr.ns == Some("xml") && attr.key == "ns_all")
506            .and_then(|attr| attr.get_as::<&str>().copied());
507
508        // Track which fields have been set
509        let num_fields = struct_def.fields.len();
510        let mut fields_set = alloc::vec![false; num_fields];
511
512        loop {
513            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
514            match event {
515                ParseEvent::StructEnd => break,
516                ParseEvent::FieldKey(key) => {
517                    // Look up field in struct fields
518                    let field_info = struct_def.fields.iter().enumerate().find(|(_, f)| {
519                        Self::field_matches_with_namespace(
520                            f,
521                            key.name.as_ref(),
522                            key.namespace.as_deref(),
523                            key.location,
524                            ns_all,
525                        )
526                    });
527
528                    if let Some((idx, _field)) = field_info {
529                        wip = wip
530                            .begin_nth_field(idx)
531                            .map_err(DeserializeError::Reflect)?;
532                        wip = self.deserialize_into(wip)?;
533                        wip = wip.end().map_err(DeserializeError::Reflect)?;
534                        fields_set[idx] = true;
535                        continue;
536                    }
537
538                    if deny_unknown_fields {
539                        return Err(DeserializeError::UnknownField(key.name.into_owned()));
540                    } else {
541                        // Unknown field - skip it
542                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
543                    }
544                }
545                other => {
546                    return Err(DeserializeError::TypeMismatch {
547                        expected: "field key or struct end",
548                        got: format!("{other:?}"),
549                    });
550                }
551            }
552        }
553
554        // Apply defaults for missing fields
555        for (idx, field) in struct_def.fields.iter().enumerate() {
556            if fields_set[idx] {
557                continue;
558            }
559
560            let field_has_default = field.has_default();
561            let field_type_has_default = field.shape().is(Characteristic::Default);
562            let field_is_option = matches!(field.shape().def, Def::Option(_));
563
564            if field_has_default || (struct_has_default && field_type_has_default) {
565                wip = wip
566                    .set_nth_field_to_default(idx)
567                    .map_err(DeserializeError::Reflect)?;
568            } else if field_is_option {
569                wip = wip
570                    .begin_field(field.name)
571                    .map_err(DeserializeError::Reflect)?;
572                wip = wip.set_default().map_err(DeserializeError::Reflect)?;
573                wip = wip.end().map_err(DeserializeError::Reflect)?;
574            } else if field.should_skip_deserializing() {
575                wip = wip
576                    .set_nth_field_to_default(idx)
577                    .map_err(DeserializeError::Reflect)?;
578            } else {
579                return Err(DeserializeError::TypeMismatch {
580                    expected: "field to be present or have default",
581                    got: format!("missing field '{}'", field.name),
582                });
583            }
584        }
585
586        Ok(wip)
587    }
588
589    /// Deserialize a struct with single-level flattened fields (original approach).
590    /// This handles simple flatten cases where there's no nested flatten or enum flatten.
591    fn deserialize_struct_single_flatten(
592        &mut self,
593        mut wip: Partial<'input, BORROW>,
594    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
595        use alloc::collections::BTreeMap;
596        use facet_core::Characteristic;
597        use facet_reflect::Resolution;
598
599        // Expect StructStart
600        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
601        if !matches!(event, ParseEvent::StructStart(_)) {
602            return Err(DeserializeError::TypeMismatch {
603                expected: "struct start",
604                got: format!("{event:?}"),
605            });
606        }
607
608        // Get struct fields for lookup
609        let struct_def = match &wip.shape().ty {
610            Type::User(UserType::Struct(def)) => def,
611            _ => {
612                return Err(DeserializeError::Unsupported(format!(
613                    "expected struct type but got {:?}",
614                    wip.shape().ty
615                )));
616            }
617        };
618
619        let struct_has_default = wip.shape().has_default_attr();
620        let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
621
622        // Extract container-level default namespace (xml::ns_all) for namespace-aware matching
623        let ns_all = wip
624            .shape()
625            .attributes
626            .iter()
627            .find(|attr| attr.ns == Some("xml") && attr.key == "ns_all")
628            .and_then(|attr| attr.get_as::<&str>().copied());
629
630        // Track which fields have been set
631        let num_fields = struct_def.fields.len();
632        let mut fields_set = alloc::vec![false; num_fields];
633
634        // Build flatten info: for each flattened field, get its inner struct fields
635        // and track which inner fields have been set
636        let mut flatten_info: alloc::vec::Vec<
637            Option<(&'static [facet_core::Field], alloc::vec::Vec<bool>)>,
638        > = alloc::vec![None; num_fields];
639
640        // Track field names across flattened structs to detect duplicates
641        let mut flatten_field_names: BTreeMap<&str, usize> = BTreeMap::new();
642
643        for (idx, field) in struct_def.fields.iter().enumerate() {
644            if field.is_flattened() {
645                // Handle Option<T> flatten by unwrapping to inner type
646                let inner_shape = match field.shape().def {
647                    Def::Option(opt) => opt.t,
648                    _ => field.shape(),
649                };
650
651                if let Type::User(UserType::Struct(inner_def)) = &inner_shape.ty {
652                    let inner_fields = inner_def.fields;
653                    let inner_set = alloc::vec![false; inner_fields.len()];
654                    flatten_info[idx] = Some((inner_fields, inner_set));
655
656                    // Check for duplicate field names across flattened structs
657                    for inner_field in inner_fields.iter() {
658                        let field_name = inner_field.rename.unwrap_or(inner_field.name);
659                        if let Some(_prev_idx) = flatten_field_names.insert(field_name, idx) {
660                            return Err(DeserializeError::Unsupported(format!(
661                                "duplicate field `{}` in flattened structs",
662                                field_name
663                            )));
664                        }
665                    }
666                }
667            }
668        }
669
670        // Enter deferred mode for flatten handling
671        let resolution = Resolution::new();
672        wip = wip
673            .begin_deferred(resolution)
674            .map_err(DeserializeError::Reflect)?;
675
676        loop {
677            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
678            match event {
679                ParseEvent::StructEnd => break,
680                ParseEvent::FieldKey(key) => {
681                    // First, look up field in direct struct fields (non-flattened)
682                    let direct_field_info = struct_def.fields.iter().enumerate().find(|(_, f)| {
683                        !f.is_flattened()
684                            && Self::field_matches_with_namespace(
685                                f,
686                                key.name.as_ref(),
687                                key.namespace.as_deref(),
688                                key.location,
689                                ns_all,
690                            )
691                    });
692
693                    if let Some((idx, _field)) = direct_field_info {
694                        wip = wip
695                            .begin_nth_field(idx)
696                            .map_err(DeserializeError::Reflect)?;
697                        wip = self.deserialize_into(wip)?;
698                        wip = wip.end().map_err(DeserializeError::Reflect)?;
699                        fields_set[idx] = true;
700                        continue;
701                    }
702
703                    // Check flattened fields for a match
704                    let mut found_flatten = false;
705                    for (flatten_idx, field) in struct_def.fields.iter().enumerate() {
706                        if !field.is_flattened() {
707                            continue;
708                        }
709                        if let Some((inner_fields, inner_set)) = flatten_info[flatten_idx].as_mut()
710                        {
711                            let inner_match = inner_fields.iter().enumerate().find(|(_, f)| {
712                                Self::field_matches_with_namespace(
713                                    f,
714                                    key.name.as_ref(),
715                                    key.namespace.as_deref(),
716                                    key.location,
717                                    ns_all,
718                                )
719                            });
720
721                            if let Some((inner_idx, _inner_field)) = inner_match {
722                                // Check if flatten field is Option - if so, wrap in Some
723                                let is_option = matches!(field.shape().def, Def::Option(_));
724                                wip = wip
725                                    .begin_nth_field(flatten_idx)
726                                    .map_err(DeserializeError::Reflect)?;
727                                if is_option {
728                                    wip = wip.begin_some().map_err(DeserializeError::Reflect)?;
729                                }
730                                wip = wip
731                                    .begin_nth_field(inner_idx)
732                                    .map_err(DeserializeError::Reflect)?;
733                                wip = self.deserialize_into(wip)?;
734                                wip = wip.end().map_err(DeserializeError::Reflect)?;
735                                if is_option {
736                                    wip = wip.end().map_err(DeserializeError::Reflect)?;
737                                }
738                                wip = wip.end().map_err(DeserializeError::Reflect)?;
739                                inner_set[inner_idx] = true;
740                                fields_set[flatten_idx] = true;
741                                found_flatten = true;
742                                break;
743                            }
744                        }
745                    }
746
747                    if found_flatten {
748                        continue;
749                    }
750
751                    if deny_unknown_fields {
752                        return Err(DeserializeError::UnknownField(key.name.into_owned()));
753                    } else {
754                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
755                    }
756                }
757                other => {
758                    return Err(DeserializeError::TypeMismatch {
759                        expected: "field key or struct end",
760                        got: format!("{other:?}"),
761                    });
762                }
763            }
764        }
765
766        // Apply defaults for missing fields
767        for (idx, field) in struct_def.fields.iter().enumerate() {
768            if field.is_flattened() {
769                if let Some((inner_fields, inner_set)) = flatten_info[idx].as_ref() {
770                    let any_inner_set = inner_set.iter().any(|&s| s);
771                    let is_option = matches!(field.shape().def, Def::Option(_));
772
773                    if any_inner_set {
774                        // Some inner fields were set - apply defaults to missing ones
775                        wip = wip
776                            .begin_nth_field(idx)
777                            .map_err(DeserializeError::Reflect)?;
778                        if is_option {
779                            wip = wip.begin_some().map_err(DeserializeError::Reflect)?;
780                        }
781                        for (inner_idx, inner_field) in inner_fields.iter().enumerate() {
782                            if inner_set[inner_idx] {
783                                continue;
784                            }
785                            let inner_has_default = inner_field.has_default();
786                            let inner_type_has_default =
787                                inner_field.shape().is(Characteristic::Default);
788                            let inner_is_option = matches!(inner_field.shape().def, Def::Option(_));
789
790                            if inner_has_default || inner_type_has_default {
791                                wip = wip
792                                    .set_nth_field_to_default(inner_idx)
793                                    .map_err(DeserializeError::Reflect)?;
794                            } else if inner_is_option {
795                                wip = wip
796                                    .begin_nth_field(inner_idx)
797                                    .map_err(DeserializeError::Reflect)?;
798                                wip = wip.set_default().map_err(DeserializeError::Reflect)?;
799                                wip = wip.end().map_err(DeserializeError::Reflect)?;
800                            } else if inner_field.should_skip_deserializing() {
801                                wip = wip
802                                    .set_nth_field_to_default(inner_idx)
803                                    .map_err(DeserializeError::Reflect)?;
804                            } else {
805                                return Err(DeserializeError::TypeMismatch {
806                                    expected: "field to be present or have default",
807                                    got: format!("missing field '{}'", inner_field.name),
808                                });
809                            }
810                        }
811                        if is_option {
812                            wip = wip.end().map_err(DeserializeError::Reflect)?;
813                        }
814                        wip = wip.end().map_err(DeserializeError::Reflect)?;
815                    } else if is_option {
816                        // No inner fields set and field is Option - set to None
817                        wip = wip
818                            .begin_nth_field(idx)
819                            .map_err(DeserializeError::Reflect)?;
820                        wip = wip.set_default().map_err(DeserializeError::Reflect)?;
821                        wip = wip.end().map_err(DeserializeError::Reflect)?;
822                    } else {
823                        // No inner fields set - try to default the whole flattened field
824                        let field_has_default = field.has_default();
825                        let field_type_has_default = field.shape().is(Characteristic::Default);
826                        if field_has_default || (struct_has_default && field_type_has_default) {
827                            wip = wip
828                                .set_nth_field_to_default(idx)
829                                .map_err(DeserializeError::Reflect)?;
830                        } else {
831                            let all_inner_can_default = inner_fields.iter().all(|f| {
832                                f.has_default()
833                                    || f.shape().is(Characteristic::Default)
834                                    || matches!(f.shape().def, Def::Option(_))
835                                    || f.should_skip_deserializing()
836                            });
837                            if all_inner_can_default {
838                                wip = wip
839                                    .begin_nth_field(idx)
840                                    .map_err(DeserializeError::Reflect)?;
841                                for (inner_idx, inner_field) in inner_fields.iter().enumerate() {
842                                    let inner_has_default = inner_field.has_default();
843                                    let inner_type_has_default =
844                                        inner_field.shape().is(Characteristic::Default);
845                                    let inner_is_option =
846                                        matches!(inner_field.shape().def, Def::Option(_));
847
848                                    if inner_has_default || inner_type_has_default {
849                                        wip = wip
850                                            .set_nth_field_to_default(inner_idx)
851                                            .map_err(DeserializeError::Reflect)?;
852                                    } else if inner_is_option {
853                                        wip = wip
854                                            .begin_nth_field(inner_idx)
855                                            .map_err(DeserializeError::Reflect)?;
856                                        wip =
857                                            wip.set_default().map_err(DeserializeError::Reflect)?;
858                                        wip = wip.end().map_err(DeserializeError::Reflect)?;
859                                    } else if inner_field.should_skip_deserializing() {
860                                        wip = wip
861                                            .set_nth_field_to_default(inner_idx)
862                                            .map_err(DeserializeError::Reflect)?;
863                                    }
864                                }
865                                wip = wip.end().map_err(DeserializeError::Reflect)?;
866                            } else {
867                                return Err(DeserializeError::TypeMismatch {
868                                    expected: "field to be present or have default",
869                                    got: format!("missing flattened field '{}'", field.name),
870                                });
871                            }
872                        }
873                    }
874                }
875                continue;
876            }
877
878            if fields_set[idx] {
879                continue;
880            }
881
882            let field_has_default = field.has_default();
883            let field_type_has_default = field.shape().is(Characteristic::Default);
884            let field_is_option = matches!(field.shape().def, Def::Option(_));
885
886            if field_has_default || (struct_has_default && field_type_has_default) {
887                wip = wip
888                    .set_nth_field_to_default(idx)
889                    .map_err(DeserializeError::Reflect)?;
890            } else if field_is_option {
891                wip = wip
892                    .begin_field(field.name)
893                    .map_err(DeserializeError::Reflect)?;
894                wip = wip.set_default().map_err(DeserializeError::Reflect)?;
895                wip = wip.end().map_err(DeserializeError::Reflect)?;
896            } else if field.should_skip_deserializing() {
897                wip = wip
898                    .set_nth_field_to_default(idx)
899                    .map_err(DeserializeError::Reflect)?;
900            } else {
901                return Err(DeserializeError::TypeMismatch {
902                    expected: "field to be present or have default",
903                    got: format!("missing field '{}'", field.name),
904                });
905            }
906        }
907
908        // Finish deferred mode
909        wip = wip.finish_deferred().map_err(DeserializeError::Reflect)?;
910
911        Ok(wip)
912    }
913
914    /// Deserialize a struct with flattened fields using facet-solver.
915    ///
916    /// This uses the solver's Schema/Resolution to handle arbitrarily nested
917    /// flatten structures by looking up the full path for each field.
918    /// It also handles flattened enums by using probing to collect keys first,
919    /// then using the Solver to disambiguate between resolutions.
920    fn deserialize_struct_with_flatten(
921        &mut self,
922        mut wip: Partial<'input, BORROW>,
923    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
924        use alloc::collections::BTreeSet;
925        use facet_core::Characteristic;
926        use facet_reflect::Resolution;
927        use facet_solver::{PathSegment, Schema, Solver};
928
929        let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
930
931        // Build the schema for this type - this recursively expands all flatten fields
932        let schema = Schema::build_auto(wip.shape())
933            .map_err(|e| DeserializeError::Unsupported(format!("failed to build schema: {e}")))?;
934
935        // Check if we have multiple resolutions (i.e., flattened enums)
936        let resolutions = schema.resolutions();
937        if resolutions.is_empty() {
938            return Err(DeserializeError::Unsupported(
939                "schema has no resolutions".into(),
940            ));
941        }
942
943        // ========== PASS 1: Probe to collect all field keys ==========
944        let probe = self
945            .parser
946            .begin_probe()
947            .map_err(DeserializeError::Parser)?;
948        let evidence = Self::collect_evidence(probe).map_err(DeserializeError::Parser)?;
949
950        // Feed keys to solver to narrow down resolutions
951        let mut solver = Solver::new(&schema);
952        for ev in &evidence {
953            solver.see_key(ev.name.clone());
954        }
955
956        // Get the resolved configuration
957        let config_handle = solver
958            .finish()
959            .map_err(|e| DeserializeError::Unsupported(format!("solver failed: {e}")))?;
960        let resolution = config_handle.resolution();
961
962        // ========== PASS 2: Parse the struct with resolved paths ==========
963        // Expect StructStart
964        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
965        if !matches!(event, ParseEvent::StructStart(_)) {
966            return Err(DeserializeError::TypeMismatch {
967                expected: "struct start",
968                got: format!("{event:?}"),
969            });
970        }
971
972        // Enter deferred mode for flatten handling
973        let reflect_resolution = Resolution::new();
974        wip = wip
975            .begin_deferred(reflect_resolution)
976            .map_err(DeserializeError::Reflect)?;
977
978        // Track which fields have been set (by serialized name - uses 'static str from resolution)
979        let mut fields_set: BTreeSet<&'static str> = BTreeSet::new();
980
981        // Track currently open path segments: (field_name, is_option, is_variant)
982        // The is_variant flag indicates if we've selected a variant at this level
983        let mut open_segments: alloc::vec::Vec<(&str, bool, bool)> = alloc::vec::Vec::new();
984
985        loop {
986            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
987            match event {
988                ParseEvent::StructEnd => break,
989                ParseEvent::FieldKey(key) => {
990                    // Look up field in the resolution
991                    if let Some(field_info) = resolution.field(key.name.as_ref()) {
992                        let segments = field_info.path.segments();
993
994                        // Check if this path ends with a Variant segment (externally-tagged enum)
995                        let ends_with_variant = segments
996                            .last()
997                            .is_some_and(|s| matches!(s, PathSegment::Variant(_, _)));
998
999                        // Extract field names from the path (excluding trailing Variant)
1000                        let field_segments: alloc::vec::Vec<&str> = segments
1001                            .iter()
1002                            .filter_map(|s| match s {
1003                                PathSegment::Field(name) => Some(*name),
1004                                PathSegment::Variant(_, _) => None,
1005                            })
1006                            .collect();
1007
1008                        // Find common prefix with currently open segments
1009                        let common_len = open_segments
1010                            .iter()
1011                            .zip(field_segments.iter())
1012                            .take_while(|((name, _, _), b)| *name == **b)
1013                            .count();
1014
1015                        // Close segments that are no longer needed (in reverse order)
1016                        while open_segments.len() > common_len {
1017                            let (_, is_option, _) = open_segments.pop().unwrap();
1018                            if is_option {
1019                                wip = wip.end().map_err(DeserializeError::Reflect)?;
1020                            }
1021                            wip = wip.end().map_err(DeserializeError::Reflect)?;
1022                        }
1023
1024                        // Open new segments
1025                        for &segment in &field_segments[common_len..] {
1026                            wip = wip
1027                                .begin_field(segment)
1028                                .map_err(DeserializeError::Reflect)?;
1029                            let is_option = matches!(wip.shape().def, Def::Option(_));
1030                            if is_option {
1031                                wip = wip.begin_some().map_err(DeserializeError::Reflect)?;
1032                            }
1033                            open_segments.push((segment, is_option, false));
1034                        }
1035
1036                        if ends_with_variant {
1037                            // For externally-tagged enums: select variant and deserialize content
1038                            if let Some(PathSegment::Variant(_, variant_name)) = segments.last() {
1039                                wip = wip
1040                                    .select_variant_named(variant_name)
1041                                    .map_err(DeserializeError::Reflect)?;
1042                                // Deserialize the variant's struct content (the nested object)
1043                                wip = self.deserialize_variant_struct_fields(wip)?;
1044                            }
1045                        } else {
1046                            // Regular field: deserialize into it
1047                            wip = self.deserialize_into(wip)?;
1048                        }
1049
1050                        // Close segments we just opened (we're done with this field)
1051                        while open_segments.len() > common_len {
1052                            let (_, is_option, _) = open_segments.pop().unwrap();
1053                            if is_option {
1054                                wip = wip.end().map_err(DeserializeError::Reflect)?;
1055                            }
1056                            wip = wip.end().map_err(DeserializeError::Reflect)?;
1057                        }
1058
1059                        // Store the static serialized_name from the resolution
1060                        fields_set.insert(field_info.serialized_name);
1061                        continue;
1062                    }
1063
1064                    if deny_unknown_fields {
1065                        return Err(DeserializeError::UnknownField(key.name.into_owned()));
1066                    } else {
1067                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1068                    }
1069                }
1070                other => {
1071                    return Err(DeserializeError::TypeMismatch {
1072                        expected: "field key or struct end",
1073                        got: format!("{other:?}"),
1074                    });
1075                }
1076            }
1077        }
1078
1079        // Close any remaining open segments
1080        while let Some((_, is_option, _)) = open_segments.pop() {
1081            if is_option {
1082                wip = wip.end().map_err(DeserializeError::Reflect)?;
1083            }
1084            wip = wip.end().map_err(DeserializeError::Reflect)?;
1085        }
1086
1087        // Handle missing fields - apply defaults
1088        // Get all fields sorted by path depth (deepest first for proper default handling)
1089        let all_fields = resolution.deserialization_order();
1090
1091        // Track which top-level flatten fields have had any sub-fields set
1092        let mut touched_top_fields: BTreeSet<&str> = BTreeSet::new();
1093        for field_name in &fields_set {
1094            if let Some(info) = resolution.field(field_name)
1095                && let Some(PathSegment::Field(top)) = info.path.segments().first()
1096            {
1097                touched_top_fields.insert(*top);
1098            }
1099        }
1100
1101        for field_info in all_fields {
1102            if fields_set.contains(field_info.serialized_name) {
1103                continue;
1104            }
1105
1106            // Skip fields that end with Variant - these are handled by enum deserialization
1107            let ends_with_variant = field_info
1108                .path
1109                .segments()
1110                .last()
1111                .is_some_and(|s| matches!(s, PathSegment::Variant(_, _)));
1112            if ends_with_variant {
1113                continue;
1114            }
1115
1116            let path_segments: alloc::vec::Vec<&str> = field_info
1117                .path
1118                .segments()
1119                .iter()
1120                .filter_map(|s| match s {
1121                    PathSegment::Field(name) => Some(*name),
1122                    PathSegment::Variant(_, _) => None,
1123                })
1124                .collect();
1125
1126            // Check if this field's parent was touched
1127            let first_segment = path_segments.first().copied();
1128            let parent_touched = first_segment
1129                .map(|s| touched_top_fields.contains(s))
1130                .unwrap_or(false);
1131
1132            // If parent wasn't touched at all, we might default the whole parent
1133            // For now, handle individual field defaults
1134            let field_has_default = field_info.field.has_default();
1135            let field_type_has_default = field_info.value_shape.is(Characteristic::Default);
1136            let field_is_option = matches!(field_info.value_shape.def, Def::Option(_));
1137
1138            if field_has_default
1139                || field_type_has_default
1140                || field_is_option
1141                || field_info.field.should_skip_deserializing()
1142            {
1143                // Navigate to the field and set default
1144                for &segment in &path_segments[..path_segments.len().saturating_sub(1)] {
1145                    wip = wip
1146                        .begin_field(segment)
1147                        .map_err(DeserializeError::Reflect)?;
1148                    if matches!(wip.shape().def, Def::Option(_)) {
1149                        wip = wip.begin_some().map_err(DeserializeError::Reflect)?;
1150                    }
1151                }
1152
1153                if let Some(&last) = path_segments.last() {
1154                    wip = wip.begin_field(last).map_err(DeserializeError::Reflect)?;
1155                    wip = wip.set_default().map_err(DeserializeError::Reflect)?;
1156                    wip = wip.end().map_err(DeserializeError::Reflect)?;
1157                }
1158
1159                // Close the path we opened
1160                for _ in 0..path_segments.len().saturating_sub(1) {
1161                    // Need to check if we're in an option
1162                    wip = wip.end().map_err(DeserializeError::Reflect)?;
1163                }
1164            } else if !parent_touched && path_segments.len() > 1 {
1165                // Parent wasn't touched and field has no default - this is OK if the whole
1166                // parent can be defaulted (handled by deferred mode)
1167                continue;
1168            } else if field_info.required {
1169                return Err(DeserializeError::TypeMismatch {
1170                    expected: "field to be present or have default",
1171                    got: format!("missing field '{}'", field_info.serialized_name),
1172                });
1173            }
1174        }
1175
1176        // Finish deferred mode
1177        wip = wip.finish_deferred().map_err(DeserializeError::Reflect)?;
1178
1179        Ok(wip)
1180    }
1181
1182    /// Deserialize the struct fields of a variant.
1183    /// Expects the variant to already be selected.
1184    fn deserialize_variant_struct_fields(
1185        &mut self,
1186        mut wip: Partial<'input, BORROW>,
1187    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1188        use facet_core::StructKind;
1189
1190        let variant = wip
1191            .selected_variant()
1192            .ok_or_else(|| DeserializeError::TypeMismatch {
1193                expected: "selected variant",
1194                got: "no variant selected".into(),
1195            })?;
1196
1197        let variant_fields = variant.data.fields;
1198        let kind = variant.data.kind;
1199
1200        // Handle based on variant kind
1201        match kind {
1202            StructKind::TupleStruct if variant_fields.len() == 1 => {
1203                // Single-element tuple variant (newtype): deserialize the inner value directly
1204                wip = wip.begin_nth_field(0).map_err(DeserializeError::Reflect)?;
1205                wip = self.deserialize_into(wip)?;
1206                wip = wip.end().map_err(DeserializeError::Reflect)?;
1207                return Ok(wip);
1208            }
1209            StructKind::TupleStruct | StructKind::Tuple => {
1210                // Multi-element tuple variant - not yet supported in this context
1211                return Err(DeserializeError::Unsupported(
1212                    "multi-element tuple variants in flatten not yet supported".into(),
1213                ));
1214            }
1215            StructKind::Unit => {
1216                // Unit variant - nothing to deserialize
1217                return Ok(wip);
1218            }
1219            StructKind::Struct => {
1220                // Struct variant - fall through to struct deserialization below
1221            }
1222        }
1223
1224        // Struct variant: deserialize as a struct with named fields
1225        // Expect StructStart for the variant content
1226        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1227        if !matches!(event, ParseEvent::StructStart(_)) {
1228            return Err(DeserializeError::TypeMismatch {
1229                expected: "struct start for variant content",
1230                got: format!("{event:?}"),
1231            });
1232        }
1233
1234        // Track which fields have been set
1235        let num_fields = variant_fields.len();
1236        let mut fields_set = alloc::vec![false; num_fields];
1237
1238        // Process all fields
1239        loop {
1240            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1241            match event {
1242                ParseEvent::StructEnd => break,
1243                ParseEvent::FieldKey(key) => {
1244                    // Look up field in variant's fields
1245                    let field_info = variant_fields.iter().enumerate().find(|(_, f)| {
1246                        Self::field_matches_with_namespace(
1247                            f,
1248                            key.name.as_ref(),
1249                            key.namespace.as_deref(),
1250                            key.location,
1251                            None,
1252                        )
1253                    });
1254
1255                    if let Some((idx, _field)) = field_info {
1256                        wip = wip
1257                            .begin_nth_field(idx)
1258                            .map_err(DeserializeError::Reflect)?;
1259                        wip = self.deserialize_into(wip)?;
1260                        wip = wip.end().map_err(DeserializeError::Reflect)?;
1261                        fields_set[idx] = true;
1262                    } else {
1263                        // Unknown field - skip
1264                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1265                    }
1266                }
1267                other => {
1268                    return Err(DeserializeError::TypeMismatch {
1269                        expected: "field key or struct end",
1270                        got: format!("{other:?}"),
1271                    });
1272                }
1273            }
1274        }
1275
1276        // Apply defaults for missing fields
1277        for (idx, field) in variant_fields.iter().enumerate() {
1278            if fields_set[idx] {
1279                continue;
1280            }
1281
1282            let field_has_default = field.has_default();
1283            let field_type_has_default = field.shape().is(facet_core::Characteristic::Default);
1284            let field_is_option = matches!(field.shape().def, Def::Option(_));
1285
1286            if field_has_default || field_type_has_default {
1287                wip = wip
1288                    .set_nth_field_to_default(idx)
1289                    .map_err(DeserializeError::Reflect)?;
1290            } else if field_is_option {
1291                wip = wip
1292                    .begin_nth_field(idx)
1293                    .map_err(DeserializeError::Reflect)?;
1294                wip = wip.set_default().map_err(DeserializeError::Reflect)?;
1295                wip = wip.end().map_err(DeserializeError::Reflect)?;
1296            } else if field.should_skip_deserializing() {
1297                wip = wip
1298                    .set_nth_field_to_default(idx)
1299                    .map_err(DeserializeError::Reflect)?;
1300            } else {
1301                return Err(DeserializeError::TypeMismatch {
1302                    expected: "field to be present or have default",
1303                    got: format!("missing field '{}'", field.name),
1304                });
1305            }
1306        }
1307
1308        Ok(wip)
1309    }
1310
1311    fn deserialize_tuple(
1312        &mut self,
1313        mut wip: Partial<'input, BORROW>,
1314    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1315        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1316
1317        // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
1318        // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
1319        let struct_mode = match event {
1320            ParseEvent::SequenceStart(_) => false,
1321            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
1322            ParseEvent::StructStart(kind) => {
1323                return Err(DeserializeError::TypeMismatch {
1324                    expected: "array",
1325                    got: kind.name().into(),
1326                });
1327            }
1328            _ => {
1329                return Err(DeserializeError::TypeMismatch {
1330                    expected: "sequence start for tuple",
1331                    got: format!("{event:?}"),
1332                });
1333            }
1334        };
1335
1336        let mut index = 0usize;
1337        loop {
1338            let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
1339
1340            // Check for end of container
1341            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
1342                self.parser.next_event().map_err(DeserializeError::Parser)?;
1343                break;
1344            }
1345
1346            // In struct mode, skip FieldKey events
1347            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
1348                self.parser.next_event().map_err(DeserializeError::Parser)?;
1349                continue;
1350            }
1351
1352            // Select field by index
1353            let field_name = alloc::string::ToString::to_string(&index);
1354            wip = wip
1355                .begin_field(&field_name)
1356                .map_err(DeserializeError::Reflect)?;
1357            wip = self.deserialize_into(wip)?;
1358            wip = wip.end().map_err(DeserializeError::Reflect)?;
1359            index += 1;
1360        }
1361
1362        Ok(wip)
1363    }
1364
1365    fn deserialize_enum(
1366        &mut self,
1367        wip: Partial<'input, BORROW>,
1368    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1369        let shape = wip.shape();
1370
1371        // Check for different tagging modes
1372        let tag_attr = shape.get_tag_attr();
1373        let content_attr = shape.get_content_attr();
1374        let is_untagged = shape.is_untagged();
1375
1376        // Determine tagging mode
1377        if is_untagged {
1378            return self.deserialize_enum_untagged(wip);
1379        }
1380
1381        if let (Some(tag_key), Some(content_key)) = (tag_attr, content_attr) {
1382            // Adjacently tagged: {"t": "VariantName", "c": {...}}
1383            return self.deserialize_enum_adjacently_tagged(wip, tag_key, content_key);
1384        }
1385
1386        if let Some(tag_key) = tag_attr {
1387            // Internally tagged: {"type": "VariantName", ...fields...}
1388            return self.deserialize_enum_internally_tagged(wip, tag_key);
1389        }
1390
1391        // Externally tagged (default): {"VariantName": {...}} or just "VariantName"
1392        self.deserialize_enum_externally_tagged(wip)
1393    }
1394
1395    fn deserialize_enum_externally_tagged(
1396        &mut self,
1397        mut wip: Partial<'input, BORROW>,
1398    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1399        let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
1400
1401        // Check for unit variant (just a string)
1402        if let ParseEvent::Scalar(ScalarValue::Str(variant_name)) = &event {
1403            self.parser.next_event().map_err(DeserializeError::Parser)?;
1404            wip = wip
1405                .select_variant_named(variant_name)
1406                .map_err(DeserializeError::Reflect)?;
1407            return Ok(wip);
1408        }
1409
1410        // Otherwise expect a struct { VariantName: ... }
1411        if !matches!(event, ParseEvent::StructStart(_)) {
1412            return Err(DeserializeError::TypeMismatch {
1413                expected: "string or struct for enum",
1414                got: format!("{event:?}"),
1415            });
1416        }
1417
1418        self.parser.next_event().map_err(DeserializeError::Parser)?; // consume StructStart
1419
1420        // Get the variant name
1421        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1422        let variant_name = match event {
1423            ParseEvent::FieldKey(key) => key.name,
1424            other => {
1425                return Err(DeserializeError::TypeMismatch {
1426                    expected: "variant name",
1427                    got: format!("{other:?}"),
1428                });
1429            }
1430        };
1431
1432        wip = wip
1433            .select_variant_named(&variant_name)
1434            .map_err(DeserializeError::Reflect)?;
1435
1436        // Deserialize the variant content
1437        wip = self.deserialize_enum_variant_content(wip)?;
1438
1439        // Consume StructEnd
1440        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1441        if !matches!(event, ParseEvent::StructEnd) {
1442            return Err(DeserializeError::TypeMismatch {
1443                expected: "struct end after enum variant",
1444                got: format!("{event:?}"),
1445            });
1446        }
1447
1448        Ok(wip)
1449    }
1450
1451    fn deserialize_enum_internally_tagged(
1452        &mut self,
1453        mut wip: Partial<'input, BORROW>,
1454        tag_key: &str,
1455    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1456        use facet_core::Characteristic;
1457
1458        // Step 1: Probe to find the tag value (handles out-of-order fields)
1459        let probe = self
1460            .parser
1461            .begin_probe()
1462            .map_err(DeserializeError::Parser)?;
1463        let evidence = Self::collect_evidence(probe).map_err(DeserializeError::Parser)?;
1464
1465        let variant_name = Self::find_tag_value(&evidence, tag_key)
1466            .ok_or_else(|| DeserializeError::TypeMismatch {
1467                expected: "tag field in internally tagged enum",
1468                got: format!("missing '{tag_key}' field"),
1469            })?
1470            .to_string();
1471
1472        // Step 2: Consume StructStart
1473        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1474        if !matches!(event, ParseEvent::StructStart(_)) {
1475            return Err(DeserializeError::TypeMismatch {
1476                expected: "struct for internally tagged enum",
1477                got: format!("{event:?}"),
1478            });
1479        }
1480
1481        // Step 3: Select the variant
1482        wip = wip
1483            .select_variant_named(&variant_name)
1484            .map_err(DeserializeError::Reflect)?;
1485
1486        // Get the selected variant info
1487        let variant = wip
1488            .selected_variant()
1489            .ok_or_else(|| DeserializeError::TypeMismatch {
1490                expected: "selected variant",
1491                got: "no variant selected".into(),
1492            })?;
1493
1494        let variant_fields = variant.data.fields;
1495
1496        // Check if this is a unit variant (no fields)
1497        if variant_fields.is_empty() || variant.data.kind == StructKind::Unit {
1498            // Consume remaining fields in the object
1499            loop {
1500                let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1501                match event {
1502                    ParseEvent::StructEnd => break,
1503                    ParseEvent::FieldKey(_) => {
1504                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1505                    }
1506                    other => {
1507                        return Err(DeserializeError::TypeMismatch {
1508                            expected: "field key or struct end",
1509                            got: format!("{other:?}"),
1510                        });
1511                    }
1512                }
1513            }
1514            return Ok(wip);
1515        }
1516
1517        // Track which fields have been set
1518        let num_fields = variant_fields.len();
1519        let mut fields_set = alloc::vec![false; num_fields];
1520
1521        // Step 4: Process all fields (they can come in any order now)
1522        loop {
1523            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1524            match event {
1525                ParseEvent::StructEnd => break,
1526                ParseEvent::FieldKey(key) => {
1527                    // Skip the tag field - already used
1528                    if key.name.as_ref() == tag_key {
1529                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1530                        continue;
1531                    }
1532
1533                    // Look up field in variant's fields
1534                    // Uses namespace-aware matching when namespace is present
1535                    let field_info = variant_fields.iter().enumerate().find(|(_, f)| {
1536                        Self::field_matches_with_namespace(
1537                            f,
1538                            key.name.as_ref(),
1539                            key.namespace.as_deref(),
1540                            key.location,
1541                            None, // Enums don't have ns_all
1542                        )
1543                    });
1544
1545                    if let Some((idx, _field)) = field_info {
1546                        wip = wip
1547                            .begin_nth_field(idx)
1548                            .map_err(DeserializeError::Reflect)?;
1549                        wip = self.deserialize_into(wip)?;
1550                        wip = wip.end().map_err(DeserializeError::Reflect)?;
1551                        fields_set[idx] = true;
1552                    } else {
1553                        // Unknown field - skip
1554                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1555                    }
1556                }
1557                other => {
1558                    return Err(DeserializeError::TypeMismatch {
1559                        expected: "field key or struct end",
1560                        got: format!("{other:?}"),
1561                    });
1562                }
1563            }
1564        }
1565
1566        // Apply defaults for missing fields
1567        for (idx, field) in variant_fields.iter().enumerate() {
1568            if fields_set[idx] {
1569                continue;
1570            }
1571
1572            let field_has_default = field.has_default();
1573            let field_type_has_default = field.shape().is(Characteristic::Default);
1574            let field_is_option = matches!(field.shape().def, Def::Option(_));
1575
1576            if field_has_default || field_type_has_default {
1577                wip = wip
1578                    .set_nth_field_to_default(idx)
1579                    .map_err(DeserializeError::Reflect)?;
1580            } else if field_is_option {
1581                wip = wip
1582                    .begin_nth_field(idx)
1583                    .map_err(DeserializeError::Reflect)?;
1584                wip = wip.set_default().map_err(DeserializeError::Reflect)?;
1585                wip = wip.end().map_err(DeserializeError::Reflect)?;
1586            } else if field.should_skip_deserializing() {
1587                wip = wip
1588                    .set_nth_field_to_default(idx)
1589                    .map_err(DeserializeError::Reflect)?;
1590            } else {
1591                return Err(DeserializeError::TypeMismatch {
1592                    expected: "field to be present or have default",
1593                    got: format!("missing field '{}'", field.name),
1594                });
1595            }
1596        }
1597
1598        Ok(wip)
1599    }
1600
1601    /// Helper to find a tag value from field evidence.
1602    fn find_tag_value<'a>(
1603        evidence: &'a [crate::FieldEvidence<'input>],
1604        tag_key: &str,
1605    ) -> Option<&'a str> {
1606        evidence
1607            .iter()
1608            .find(|e| e.name == tag_key)
1609            .and_then(|e| match &e.scalar_value {
1610                Some(ScalarValue::Str(s)) => Some(s.as_ref()),
1611                _ => None,
1612            })
1613    }
1614
1615    /// Helper to collect all evidence from a probe stream.
1616    fn collect_evidence<S: crate::ProbeStream<'input, Error = P::Error>>(
1617        mut probe: S,
1618    ) -> Result<alloc::vec::Vec<crate::FieldEvidence<'input>>, P::Error> {
1619        let mut evidence = alloc::vec::Vec::new();
1620        while let Some(ev) = probe.next()? {
1621            evidence.push(ev);
1622        }
1623        Ok(evidence)
1624    }
1625
1626    fn deserialize_enum_adjacently_tagged(
1627        &mut self,
1628        mut wip: Partial<'input, BORROW>,
1629        tag_key: &str,
1630        content_key: &str,
1631    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1632        // Step 1: Probe to find the tag value (handles out-of-order fields)
1633        let probe = self
1634            .parser
1635            .begin_probe()
1636            .map_err(DeserializeError::Parser)?;
1637        let evidence = Self::collect_evidence(probe).map_err(DeserializeError::Parser)?;
1638
1639        let variant_name = Self::find_tag_value(&evidence, tag_key)
1640            .ok_or_else(|| DeserializeError::TypeMismatch {
1641                expected: "tag field in adjacently tagged enum",
1642                got: format!("missing '{tag_key}' field"),
1643            })?
1644            .to_string();
1645
1646        // Step 2: Consume StructStart
1647        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1648        if !matches!(event, ParseEvent::StructStart(_)) {
1649            return Err(DeserializeError::TypeMismatch {
1650                expected: "struct for adjacently tagged enum",
1651                got: format!("{event:?}"),
1652            });
1653        }
1654
1655        // Step 3: Select the variant
1656        wip = wip
1657            .select_variant_named(&variant_name)
1658            .map_err(DeserializeError::Reflect)?;
1659
1660        // Step 4: Process fields in any order
1661        let mut content_seen = false;
1662        loop {
1663            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1664            match event {
1665                ParseEvent::StructEnd => break,
1666                ParseEvent::FieldKey(key) => {
1667                    if key.name.as_ref() == tag_key {
1668                        // Skip the tag field - already used
1669                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1670                    } else if key.name.as_ref() == content_key {
1671                        // Deserialize the content
1672                        wip = self.deserialize_enum_variant_content(wip)?;
1673                        content_seen = true;
1674                    } else {
1675                        // Unknown field - skip
1676                        self.parser.skip_value().map_err(DeserializeError::Parser)?;
1677                    }
1678                }
1679                other => {
1680                    return Err(DeserializeError::TypeMismatch {
1681                        expected: "field key or struct end",
1682                        got: format!("{other:?}"),
1683                    });
1684                }
1685            }
1686        }
1687
1688        // If no content field was present, it's a unit variant (already selected above)
1689        if !content_seen {
1690            // Check if the variant expects content
1691            let variant = wip.selected_variant();
1692            if let Some(v) = variant
1693                && v.data.kind != StructKind::Unit
1694                && !v.data.fields.is_empty()
1695            {
1696                return Err(DeserializeError::TypeMismatch {
1697                    expected: "content field for non-unit variant",
1698                    got: format!("missing '{content_key}' field"),
1699                });
1700            }
1701        }
1702
1703        Ok(wip)
1704    }
1705
1706    fn deserialize_enum_variant_content(
1707        &mut self,
1708        mut wip: Partial<'input, BORROW>,
1709    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1710        use facet_core::Characteristic;
1711
1712        // Get the selected variant's info
1713        let variant = wip
1714            .selected_variant()
1715            .ok_or_else(|| DeserializeError::TypeMismatch {
1716                expected: "selected variant",
1717                got: "no variant selected".into(),
1718            })?;
1719
1720        let variant_kind = variant.data.kind;
1721        let variant_fields = variant.data.fields;
1722
1723        match variant_kind {
1724            StructKind::Unit => {
1725                // Unit variant - nothing to deserialize
1726                // But we might have gotten here with content that should be consumed
1727                Ok(wip)
1728            }
1729            StructKind::Tuple | StructKind::TupleStruct => {
1730                if variant_fields.len() == 1 {
1731                    // Newtype variant - content is the single field's value
1732                    wip = wip.begin_nth_field(0).map_err(DeserializeError::Reflect)?;
1733                    wip = self.deserialize_into(wip)?;
1734                    wip = wip.end().map_err(DeserializeError::Reflect)?;
1735                } else {
1736                    // Multi-field tuple variant - expect array or struct (for XML)
1737                    let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1738
1739                    // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
1740                    let struct_mode = match event {
1741                        ParseEvent::SequenceStart(_) => false,
1742                        ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
1743                        ParseEvent::StructStart(kind) => {
1744                            return Err(DeserializeError::TypeMismatch {
1745                                expected: "array",
1746                                got: kind.name().into(),
1747                            });
1748                        }
1749                        _ => {
1750                            return Err(DeserializeError::TypeMismatch {
1751                                expected: "sequence for tuple variant",
1752                                got: format!("{event:?}"),
1753                            });
1754                        }
1755                    };
1756
1757                    let mut idx = 0;
1758                    while idx < variant_fields.len() {
1759                        // In struct mode, skip FieldKey events
1760                        if struct_mode {
1761                            let event =
1762                                self.parser.peek_event().map_err(DeserializeError::Parser)?;
1763                            if matches!(event, ParseEvent::FieldKey(_)) {
1764                                self.parser.next_event().map_err(DeserializeError::Parser)?;
1765                                continue;
1766                            }
1767                        }
1768
1769                        wip = wip
1770                            .begin_nth_field(idx)
1771                            .map_err(DeserializeError::Reflect)?;
1772                        wip = self.deserialize_into(wip)?;
1773                        wip = wip.end().map_err(DeserializeError::Reflect)?;
1774                        idx += 1;
1775                    }
1776
1777                    let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1778                    if !matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
1779                        return Err(DeserializeError::TypeMismatch {
1780                            expected: "sequence end for tuple variant",
1781                            got: format!("{event:?}"),
1782                        });
1783                    }
1784                }
1785                Ok(wip)
1786            }
1787            StructKind::Struct => {
1788                // Struct variant - expect object with fields
1789                let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1790                if !matches!(event, ParseEvent::StructStart(_)) {
1791                    return Err(DeserializeError::TypeMismatch {
1792                        expected: "struct for struct variant",
1793                        got: format!("{event:?}"),
1794                    });
1795                }
1796
1797                let num_fields = variant_fields.len();
1798                let mut fields_set = alloc::vec![false; num_fields];
1799
1800                loop {
1801                    let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
1802                    match event {
1803                        ParseEvent::StructEnd => break,
1804                        ParseEvent::FieldKey(key) => {
1805                            // Uses namespace-aware matching when namespace is present
1806                            let field_info = variant_fields.iter().enumerate().find(|(_, f)| {
1807                                Self::field_matches_with_namespace(
1808                                    f,
1809                                    key.name.as_ref(),
1810                                    key.namespace.as_deref(),
1811                                    key.location,
1812                                    None, // Enums don't have ns_all
1813                                )
1814                            });
1815
1816                            if let Some((idx, _field)) = field_info {
1817                                wip = wip
1818                                    .begin_nth_field(idx)
1819                                    .map_err(DeserializeError::Reflect)?;
1820                                wip = self.deserialize_into(wip)?;
1821                                wip = wip.end().map_err(DeserializeError::Reflect)?;
1822                                fields_set[idx] = true;
1823                            } else {
1824                                // Unknown field - skip
1825                                self.parser.skip_value().map_err(DeserializeError::Parser)?;
1826                            }
1827                        }
1828                        other => {
1829                            return Err(DeserializeError::TypeMismatch {
1830                                expected: "field key or struct end",
1831                                got: format!("{other:?}"),
1832                            });
1833                        }
1834                    }
1835                }
1836
1837                // Apply defaults for missing fields
1838                for (idx, field) in variant_fields.iter().enumerate() {
1839                    if fields_set[idx] {
1840                        continue;
1841                    }
1842
1843                    let field_has_default = field.has_default();
1844                    let field_type_has_default = field.shape().is(Characteristic::Default);
1845                    let field_is_option = matches!(field.shape().def, Def::Option(_));
1846
1847                    if field_has_default || field_type_has_default {
1848                        wip = wip
1849                            .set_nth_field_to_default(idx)
1850                            .map_err(DeserializeError::Reflect)?;
1851                    } else if field_is_option {
1852                        wip = wip
1853                            .begin_nth_field(idx)
1854                            .map_err(DeserializeError::Reflect)?;
1855                        wip = wip.set_default().map_err(DeserializeError::Reflect)?;
1856                        wip = wip.end().map_err(DeserializeError::Reflect)?;
1857                    } else if field.should_skip_deserializing() {
1858                        wip = wip
1859                            .set_nth_field_to_default(idx)
1860                            .map_err(DeserializeError::Reflect)?;
1861                    } else {
1862                        return Err(DeserializeError::TypeMismatch {
1863                            expected: "field to be present or have default",
1864                            got: format!("missing field '{}'", field.name),
1865                        });
1866                    }
1867                }
1868
1869                Ok(wip)
1870            }
1871        }
1872    }
1873
1874    fn deserialize_enum_untagged(
1875        &mut self,
1876        mut wip: Partial<'input, BORROW>,
1877    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
1878        use facet_solver::VariantsByFormat;
1879
1880        let shape = wip.shape();
1881        let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
1882            DeserializeError::Unsupported("expected enum type for untagged".into())
1883        })?;
1884
1885        let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
1886
1887        match &event {
1888            ParseEvent::Scalar(scalar) => {
1889                // Try unit variants for null
1890                if matches!(scalar, ScalarValue::Null)
1891                    && let Some(variant) = variants_by_format.unit_variants.first()
1892                {
1893                    wip = wip
1894                        .select_variant_named(variant.name)
1895                        .map_err(DeserializeError::Reflect)?;
1896                    // Consume the null
1897                    self.parser.next_event().map_err(DeserializeError::Parser)?;
1898                    return Ok(wip);
1899                }
1900
1901                // Try unit variants for string values (match variant name)
1902                // This handles untagged enums with only unit variants like:
1903                // #[facet(untagged)] enum Color { Red, Green, Blue }
1904                // which deserialize from "Red", "Green", "Blue"
1905                if let ScalarValue::Str(s) = scalar {
1906                    for variant in &variants_by_format.unit_variants {
1907                        // Match against variant name or rename attribute
1908                        let variant_display_name = variant
1909                            .get_builtin_attr("rename")
1910                            .and_then(|attr| attr.get_as::<&str>().copied())
1911                            .unwrap_or(variant.name);
1912                        if s.as_ref() == variant_display_name {
1913                            wip = wip
1914                                .select_variant_named(variant.name)
1915                                .map_err(DeserializeError::Reflect)?;
1916                            // Consume the string
1917                            self.parser.next_event().map_err(DeserializeError::Parser)?;
1918                            return Ok(wip);
1919                        }
1920                    }
1921                }
1922
1923                // Try scalar variants - match by type
1924                for (variant, inner_shape) in &variants_by_format.scalar_variants {
1925                    if self.scalar_matches_shape(scalar, inner_shape) {
1926                        wip = wip
1927                            .select_variant_named(variant.name)
1928                            .map_err(DeserializeError::Reflect)?;
1929                        wip = self.deserialize_enum_variant_content(wip)?;
1930                        return Ok(wip);
1931                    }
1932                }
1933
1934                Err(DeserializeError::TypeMismatch {
1935                    expected: "matching untagged variant for scalar",
1936                    got: format!("{:?}", scalar),
1937                })
1938            }
1939            ParseEvent::StructStart(_) => {
1940                // For struct input, use first struct variant
1941                // TODO: Use solve_variant for proper field-based matching
1942                if let Some(variant) = variants_by_format.struct_variants.first() {
1943                    wip = wip
1944                        .select_variant_named(variant.name)
1945                        .map_err(DeserializeError::Reflect)?;
1946                    wip = self.deserialize_enum_variant_content(wip)?;
1947                    return Ok(wip);
1948                }
1949
1950                Err(DeserializeError::Unsupported(
1951                    "no struct variant found for untagged enum with struct input".into(),
1952                ))
1953            }
1954            ParseEvent::SequenceStart(_) => {
1955                // For sequence input, use first tuple variant
1956                if let Some((variant, _arity)) = variants_by_format.tuple_variants.first() {
1957                    wip = wip
1958                        .select_variant_named(variant.name)
1959                        .map_err(DeserializeError::Reflect)?;
1960                    wip = self.deserialize_enum_variant_content(wip)?;
1961                    return Ok(wip);
1962                }
1963
1964                Err(DeserializeError::Unsupported(
1965                    "no tuple variant found for untagged enum with sequence input".into(),
1966                ))
1967            }
1968            _ => Err(DeserializeError::TypeMismatch {
1969                expected: "scalar, struct, or sequence for untagged enum",
1970                got: format!("{:?}", event),
1971            }),
1972        }
1973    }
1974
1975    fn scalar_matches_shape(
1976        &self,
1977        scalar: &ScalarValue<'input>,
1978        shape: &'static facet_core::Shape,
1979    ) -> bool {
1980        use facet_core::ScalarType;
1981
1982        let Some(scalar_type) = shape.scalar_type() else {
1983            // Not a scalar type - check for Option wrapping null
1984            if matches!(scalar, ScalarValue::Null) {
1985                return matches!(shape.def, Def::Option(_));
1986            }
1987            return false;
1988        };
1989
1990        match scalar {
1991            ScalarValue::Bool(_) => matches!(scalar_type, ScalarType::Bool),
1992            ScalarValue::I64(_) => matches!(
1993                scalar_type,
1994                ScalarType::I8
1995                    | ScalarType::I16
1996                    | ScalarType::I32
1997                    | ScalarType::I64
1998                    | ScalarType::I128
1999                    | ScalarType::ISize
2000            ),
2001            ScalarValue::U64(_) => matches!(
2002                scalar_type,
2003                ScalarType::U8
2004                    | ScalarType::U16
2005                    | ScalarType::U32
2006                    | ScalarType::U64
2007                    | ScalarType::U128
2008                    | ScalarType::USize
2009            ),
2010            ScalarValue::F64(_) => matches!(scalar_type, ScalarType::F32 | ScalarType::F64),
2011            ScalarValue::Str(_) => matches!(
2012                scalar_type,
2013                ScalarType::String | ScalarType::Str | ScalarType::CowStr | ScalarType::Char
2014            ),
2015            ScalarValue::Bytes(_) => {
2016                // Bytes don't have a ScalarType - would need to check for Vec<u8> or [u8]
2017                false
2018            }
2019            ScalarValue::Null => {
2020                // Null matches Unit type
2021                matches!(scalar_type, ScalarType::Unit)
2022            }
2023        }
2024    }
2025
2026    fn deserialize_list(
2027        &mut self,
2028        mut wip: Partial<'input, BORROW>,
2029    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2030        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
2031
2032        // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
2033        // In struct mode, we skip FieldKey events and treat values as sequence items
2034        // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
2035        let struct_mode = match event {
2036            ParseEvent::SequenceStart(_) => false,
2037            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
2038            ParseEvent::StructStart(kind) => {
2039                return Err(DeserializeError::TypeMismatch {
2040                    expected: "array",
2041                    got: kind.name().into(),
2042                });
2043            }
2044            _ => {
2045                return Err(DeserializeError::TypeMismatch {
2046                    expected: "sequence start",
2047                    got: format!("{event:?}"),
2048                });
2049            }
2050        };
2051
2052        // Initialize the list
2053        wip = wip.begin_list().map_err(DeserializeError::Reflect)?;
2054
2055        loop {
2056            let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
2057
2058            // Check for end of container
2059            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
2060                self.parser.next_event().map_err(DeserializeError::Parser)?;
2061                break;
2062            }
2063
2064            // In struct mode, skip FieldKey events (they're just labels for items)
2065            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
2066                self.parser.next_event().map_err(DeserializeError::Parser)?;
2067                continue;
2068            }
2069
2070            wip = wip.begin_list_item().map_err(DeserializeError::Reflect)?;
2071            wip = self.deserialize_into(wip)?;
2072            wip = wip.end().map_err(DeserializeError::Reflect)?;
2073        }
2074
2075        Ok(wip)
2076    }
2077
2078    fn deserialize_array(
2079        &mut self,
2080        mut wip: Partial<'input, BORROW>,
2081    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2082        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
2083
2084        // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
2085        // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
2086        let struct_mode = match event {
2087            ParseEvent::SequenceStart(_) => false,
2088            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
2089            ParseEvent::StructStart(kind) => {
2090                return Err(DeserializeError::TypeMismatch {
2091                    expected: "array",
2092                    got: kind.name().into(),
2093                });
2094            }
2095            _ => {
2096                return Err(DeserializeError::TypeMismatch {
2097                    expected: "sequence start for array",
2098                    got: format!("{event:?}"),
2099                });
2100            }
2101        };
2102
2103        let mut index = 0usize;
2104        loop {
2105            let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
2106
2107            // Check for end of container
2108            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
2109                self.parser.next_event().map_err(DeserializeError::Parser)?;
2110                break;
2111            }
2112
2113            // In struct mode, skip FieldKey events
2114            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
2115                self.parser.next_event().map_err(DeserializeError::Parser)?;
2116                continue;
2117            }
2118
2119            wip = wip
2120                .begin_nth_field(index)
2121                .map_err(DeserializeError::Reflect)?;
2122            wip = self.deserialize_into(wip)?;
2123            wip = wip.end().map_err(DeserializeError::Reflect)?;
2124            index += 1;
2125        }
2126
2127        Ok(wip)
2128    }
2129
2130    fn deserialize_set(
2131        &mut self,
2132        mut wip: Partial<'input, BORROW>,
2133    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2134        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
2135
2136        // Accept either SequenceStart (JSON arrays) or StructStart (XML elements)
2137        // Only accept StructStart if the container kind is ambiguous (e.g., XML Element)
2138        let struct_mode = match event {
2139            ParseEvent::SequenceStart(_) => false,
2140            ParseEvent::StructStart(kind) if kind.is_ambiguous() => true,
2141            ParseEvent::StructStart(kind) => {
2142                return Err(DeserializeError::TypeMismatch {
2143                    expected: "array",
2144                    got: kind.name().into(),
2145                });
2146            }
2147            _ => {
2148                return Err(DeserializeError::TypeMismatch {
2149                    expected: "sequence start for set",
2150                    got: format!("{event:?}"),
2151                });
2152            }
2153        };
2154
2155        // Initialize the set
2156        wip = wip.begin_set().map_err(DeserializeError::Reflect)?;
2157
2158        loop {
2159            let event = self.parser.peek_event().map_err(DeserializeError::Parser)?;
2160
2161            // Check for end of container
2162            if matches!(event, ParseEvent::SequenceEnd | ParseEvent::StructEnd) {
2163                self.parser.next_event().map_err(DeserializeError::Parser)?;
2164                break;
2165            }
2166
2167            // In struct mode, skip FieldKey events
2168            if struct_mode && matches!(event, ParseEvent::FieldKey(_)) {
2169                self.parser.next_event().map_err(DeserializeError::Parser)?;
2170                continue;
2171            }
2172
2173            wip = wip.begin_set_item().map_err(DeserializeError::Reflect)?;
2174            wip = self.deserialize_into(wip)?;
2175            wip = wip.end().map_err(DeserializeError::Reflect)?;
2176        }
2177
2178        Ok(wip)
2179    }
2180
2181    fn deserialize_map(
2182        &mut self,
2183        mut wip: Partial<'input, BORROW>,
2184    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2185        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
2186        if !matches!(event, ParseEvent::StructStart(_)) {
2187            return Err(DeserializeError::TypeMismatch {
2188                expected: "struct start for map",
2189                got: format!("{event:?}"),
2190            });
2191        }
2192
2193        // Initialize the map
2194        wip = wip.begin_map().map_err(DeserializeError::Reflect)?;
2195
2196        loop {
2197            let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
2198            match event {
2199                ParseEvent::StructEnd => break,
2200                ParseEvent::FieldKey(key) => {
2201                    // Begin key
2202                    wip = wip.begin_key().map_err(DeserializeError::Reflect)?;
2203                    wip = wip
2204                        .set(key.name.into_owned())
2205                        .map_err(DeserializeError::Reflect)?;
2206                    wip = wip.end().map_err(DeserializeError::Reflect)?;
2207
2208                    // Begin value
2209                    wip = wip.begin_value().map_err(DeserializeError::Reflect)?;
2210                    wip = self.deserialize_into(wip)?;
2211                    wip = wip.end().map_err(DeserializeError::Reflect)?;
2212                }
2213                other => {
2214                    return Err(DeserializeError::TypeMismatch {
2215                        expected: "field key or struct end for map",
2216                        got: format!("{other:?}"),
2217                    });
2218                }
2219            }
2220        }
2221
2222        Ok(wip)
2223    }
2224
2225    fn deserialize_scalar(
2226        &mut self,
2227        mut wip: Partial<'input, BORROW>,
2228    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2229        let event = self.parser.next_event().map_err(DeserializeError::Parser)?;
2230
2231        match event {
2232            ParseEvent::Scalar(scalar) => {
2233                wip = self.set_scalar(wip, scalar)?;
2234                Ok(wip)
2235            }
2236            other => Err(DeserializeError::TypeMismatch {
2237                expected: "scalar value",
2238                got: format!("{other:?}"),
2239            }),
2240        }
2241    }
2242
2243    fn set_scalar(
2244        &mut self,
2245        mut wip: Partial<'input, BORROW>,
2246        scalar: ScalarValue<'input>,
2247    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2248        let shape = wip.shape();
2249
2250        match scalar {
2251            ScalarValue::Null => {
2252                wip = wip.set_default().map_err(DeserializeError::Reflect)?;
2253            }
2254            ScalarValue::Bool(b) => {
2255                wip = wip.set(b).map_err(DeserializeError::Reflect)?;
2256            }
2257            ScalarValue::I64(n) => {
2258                // Handle signed types
2259                if shape.type_identifier == "i8" {
2260                    wip = wip.set(n as i8).map_err(DeserializeError::Reflect)?;
2261                } else if shape.type_identifier == "i16" {
2262                    wip = wip.set(n as i16).map_err(DeserializeError::Reflect)?;
2263                } else if shape.type_identifier == "i32" {
2264                    wip = wip.set(n as i32).map_err(DeserializeError::Reflect)?;
2265                } else if shape.type_identifier == "i64" {
2266                    wip = wip.set(n).map_err(DeserializeError::Reflect)?;
2267                } else if shape.type_identifier == "i128" {
2268                    wip = wip.set(n as i128).map_err(DeserializeError::Reflect)?;
2269                } else if shape.type_identifier == "isize" {
2270                    wip = wip.set(n as isize).map_err(DeserializeError::Reflect)?;
2271                // Handle unsigned types (I64 can fit in unsigned if non-negative)
2272                } else if shape.type_identifier == "u8" {
2273                    wip = wip.set(n as u8).map_err(DeserializeError::Reflect)?;
2274                } else if shape.type_identifier == "u16" {
2275                    wip = wip.set(n as u16).map_err(DeserializeError::Reflect)?;
2276                } else if shape.type_identifier == "u32" {
2277                    wip = wip.set(n as u32).map_err(DeserializeError::Reflect)?;
2278                } else if shape.type_identifier == "u64" {
2279                    wip = wip.set(n as u64).map_err(DeserializeError::Reflect)?;
2280                } else if shape.type_identifier == "u128" {
2281                    wip = wip.set(n as u128).map_err(DeserializeError::Reflect)?;
2282                } else if shape.type_identifier == "usize" {
2283                    wip = wip.set(n as usize).map_err(DeserializeError::Reflect)?;
2284                // Handle floats
2285                } else if shape.type_identifier == "f32" {
2286                    wip = wip.set(n as f32).map_err(DeserializeError::Reflect)?;
2287                } else if shape.type_identifier == "f64" {
2288                    wip = wip.set(n as f64).map_err(DeserializeError::Reflect)?;
2289                // Handle String - stringify the number
2290                } else if shape.type_identifier == "String" {
2291                    wip = wip
2292                        .set(alloc::string::ToString::to_string(&n))
2293                        .map_err(DeserializeError::Reflect)?;
2294                } else {
2295                    wip = wip.set(n).map_err(DeserializeError::Reflect)?;
2296                }
2297            }
2298            ScalarValue::U64(n) => {
2299                // Handle unsigned types
2300                if shape.type_identifier == "u8" {
2301                    wip = wip.set(n as u8).map_err(DeserializeError::Reflect)?;
2302                } else if shape.type_identifier == "u16" {
2303                    wip = wip.set(n as u16).map_err(DeserializeError::Reflect)?;
2304                } else if shape.type_identifier == "u32" {
2305                    wip = wip.set(n as u32).map_err(DeserializeError::Reflect)?;
2306                } else if shape.type_identifier == "u64" {
2307                    wip = wip.set(n).map_err(DeserializeError::Reflect)?;
2308                } else if shape.type_identifier == "u128" {
2309                    wip = wip.set(n as u128).map_err(DeserializeError::Reflect)?;
2310                } else if shape.type_identifier == "usize" {
2311                    wip = wip.set(n as usize).map_err(DeserializeError::Reflect)?;
2312                // Handle signed types (U64 can fit in signed if small enough)
2313                } else if shape.type_identifier == "i8" {
2314                    wip = wip.set(n as i8).map_err(DeserializeError::Reflect)?;
2315                } else if shape.type_identifier == "i16" {
2316                    wip = wip.set(n as i16).map_err(DeserializeError::Reflect)?;
2317                } else if shape.type_identifier == "i32" {
2318                    wip = wip.set(n as i32).map_err(DeserializeError::Reflect)?;
2319                } else if shape.type_identifier == "i64" {
2320                    wip = wip.set(n as i64).map_err(DeserializeError::Reflect)?;
2321                } else if shape.type_identifier == "i128" {
2322                    wip = wip.set(n as i128).map_err(DeserializeError::Reflect)?;
2323                } else if shape.type_identifier == "isize" {
2324                    wip = wip.set(n as isize).map_err(DeserializeError::Reflect)?;
2325                // Handle floats
2326                } else if shape.type_identifier == "f32" {
2327                    wip = wip.set(n as f32).map_err(DeserializeError::Reflect)?;
2328                } else if shape.type_identifier == "f64" {
2329                    wip = wip.set(n as f64).map_err(DeserializeError::Reflect)?;
2330                // Handle String - stringify the number
2331                } else if shape.type_identifier == "String" {
2332                    wip = wip
2333                        .set(alloc::string::ToString::to_string(&n))
2334                        .map_err(DeserializeError::Reflect)?;
2335                } else {
2336                    wip = wip.set(n).map_err(DeserializeError::Reflect)?;
2337                }
2338            }
2339            ScalarValue::F64(n) => {
2340                if shape.type_identifier == "f32" {
2341                    wip = wip.set(n as f32).map_err(DeserializeError::Reflect)?;
2342                } else {
2343                    wip = wip.set(n).map_err(DeserializeError::Reflect)?;
2344                }
2345            }
2346            ScalarValue::Str(s) => {
2347                // Try parse_from_str first if the type supports it
2348                if shape.vtable.has_parse() {
2349                    wip = wip
2350                        .parse_from_str(s.as_ref())
2351                        .map_err(DeserializeError::Reflect)?;
2352                } else {
2353                    wip = self.set_string_value(wip, s)?;
2354                }
2355            }
2356            ScalarValue::Bytes(b) => {
2357                wip = wip.set(b.into_owned()).map_err(DeserializeError::Reflect)?;
2358            }
2359        }
2360
2361        Ok(wip)
2362    }
2363
2364    /// Set a string value, handling `&str`, `Cow<str>`, and `String` appropriately.
2365    fn set_string_value(
2366        &mut self,
2367        mut wip: Partial<'input, BORROW>,
2368        s: Cow<'input, str>,
2369    ) -> Result<Partial<'input, BORROW>, DeserializeError<P::Error>> {
2370        let shape = wip.shape();
2371
2372        // Check if target is &str (shared reference to str)
2373        if let Def::Pointer(ptr_def) = shape.def
2374            && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
2375            && ptr_def
2376                .pointee()
2377                .is_some_and(|p| p.type_identifier == "str")
2378        {
2379            // In owned mode, we cannot borrow from input at all
2380            if !BORROW {
2381                return Err(DeserializeError::CannotBorrow {
2382                    message: "cannot deserialize into &str when borrowing is disabled - use String or Cow<str> instead".into(),
2383                });
2384            }
2385            match s {
2386                Cow::Borrowed(borrowed) => {
2387                    wip = wip.set(borrowed).map_err(DeserializeError::Reflect)?;
2388                    return Ok(wip);
2389                }
2390                Cow::Owned(_) => {
2391                    return Err(DeserializeError::CannotBorrow {
2392                        message: "cannot borrow &str from string containing escape sequences - use String or Cow<str> instead".into(),
2393                    });
2394                }
2395            }
2396        }
2397
2398        // Check if target is Cow<str>
2399        if let Def::Pointer(ptr_def) = shape.def
2400            && matches!(ptr_def.known, Some(KnownPointer::Cow))
2401            && ptr_def
2402                .pointee()
2403                .is_some_and(|p| p.type_identifier == "str")
2404        {
2405            wip = wip.set(s).map_err(DeserializeError::Reflect)?;
2406            return Ok(wip);
2407        }
2408
2409        // Default: convert to owned String
2410        wip = wip.set(s.into_owned()).map_err(DeserializeError::Reflect)?;
2411        Ok(wip)
2412    }
2413}
2414
2415/// Error produced by [`FormatDeserializer`].
2416#[derive(Debug)]
2417pub enum DeserializeError<E> {
2418    /// Error emitted by the format-specific parser.
2419    Parser(E),
2420    /// Reflection error from Partial operations.
2421    Reflect(ReflectError),
2422    /// Type mismatch during deserialization.
2423    TypeMismatch {
2424        /// The expected type or token.
2425        expected: &'static str,
2426        /// The actual type or token that was encountered.
2427        got: String,
2428    },
2429    /// Unsupported type or operation.
2430    Unsupported(String),
2431    /// Unknown field encountered when deny_unknown_fields is set.
2432    UnknownField(String),
2433    /// Cannot borrow string from input (e.g., escaped string into &str).
2434    CannotBorrow {
2435        /// Description of why borrowing failed.
2436        message: String,
2437    },
2438    /// Required field missing from input.
2439    MissingField {
2440        /// The field that is missing.
2441        field: &'static str,
2442        /// The type that contains the field.
2443        type_name: &'static str,
2444    },
2445}
2446
2447impl<E: fmt::Display> fmt::Display for DeserializeError<E> {
2448    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2449        match self {
2450            DeserializeError::Parser(err) => write!(f, "{err}"),
2451            DeserializeError::Reflect(err) => write!(f, "reflection error: {err}"),
2452            DeserializeError::TypeMismatch { expected, got } => {
2453                write!(f, "type mismatch: expected {expected}, got {got}")
2454            }
2455            DeserializeError::Unsupported(msg) => write!(f, "unsupported: {msg}"),
2456            DeserializeError::UnknownField(field) => write!(f, "unknown field: {field}"),
2457            DeserializeError::CannotBorrow { message } => write!(f, "{message}"),
2458            DeserializeError::MissingField { field, type_name } => {
2459                write!(f, "missing field `{field}` in type `{type_name}`")
2460            }
2461        }
2462    }
2463}
2464
2465impl<E: fmt::Debug + fmt::Display> std::error::Error for DeserializeError<E> {}