Skip to main content

facet_postcard/
parser.rs

1//! Postcard parser implementing FormatParser and FormatJitParser.
2//!
3//! Postcard is NOT a self-describing format, but Tier-0 deserialization is supported
4//! via the `hint_struct_fields` mechanism. The driver tells the parser how many fields
5//! to expect, and the parser emits `OrderedField` events accordingly.
6
7use alloc::borrow::Cow;
8use alloc::vec::Vec;
9
10use crate::DEFAULT_MAX_COLLECTION_ELEMENTS;
11use crate::error::codes;
12use facet_format::{
13    ContainerKind, DeserializeErrorKind, EnumVariantHint, FieldKey, FieldLocationHint,
14    FormatParser, ParseError, ParseEvent, ParseEventKind, SavePoint, ScalarTypeHint, ScalarValue,
15};
16use facet_reflect::Span;
17
18/// Create a ParseError from an error code and position.
19fn error_from_code(code: i32, pos: usize) -> ParseError {
20    let message = match code {
21        codes::UNEXPECTED_EOF | codes::UNEXPECTED_END_OF_INPUT => "unexpected end of input",
22        codes::VARINT_OVERFLOW => "varint overflow",
23        codes::SEQ_UNDERFLOW => "sequence underflow",
24        codes::INVALID_BOOL => "invalid boolean value",
25        codes::INVALID_UTF8 => "invalid UTF-8",
26        codes::INVALID_OPTION_DISCRIMINANT => "invalid option discriminant",
27        codes::INVALID_ENUM_DISCRIMINANT => "invalid enum discriminant",
28        codes::UNSUPPORTED_OPAQUE_TYPE => "unsupported opaque type",
29        codes::COLLECTION_TOO_LARGE => "collection length exceeds maximum",
30        codes::UNSUPPORTED => "unsupported operation",
31        _ => "unknown error",
32    };
33    ParseError::new(
34        Span::new(pos, 1),
35        DeserializeErrorKind::InvalidValue {
36            message: message.into(),
37        },
38    )
39}
40
41/// Stored variant metadata for enum parsing.
42#[derive(Debug, Clone)]
43struct VariantMeta {
44    name: String,
45    kind: facet_core::StructKind,
46    field_count: usize,
47}
48
49/// Parser state for tracking nested structures.
50#[derive(Debug, Clone)]
51enum ParserState {
52    /// At the top level or after completing a value.
53    Ready,
54    /// Inside a struct, tracking remaining fields.
55    InStruct { remaining_fields: usize },
56    /// Inside a sequence, tracking remaining elements.
57    InSequence { remaining_elements: u64 },
58    /// Inside an enum variant, tracking parsing progress.
59    InEnum {
60        variant_name: String,
61        variant_kind: facet_core::StructKind,
62        variant_field_count: usize,
63        field_key_emitted: bool,
64        /// For multi-field variants, whether we've emitted the inner wrapper start
65        wrapper_start_emitted: bool,
66        /// For multi-field variants, whether we've emitted the inner wrapper end
67        wrapper_end_emitted: bool,
68    },
69    /// Inside a map, tracking remaining entries.
70    /// Maps are serialized as sequences of key-value pairs.
71    InMap { remaining_entries: u64 },
72    /// Inside a dynamically tagged array (facet_value::Value array).
73    InDynamicArray { remaining_elements: u64 },
74    /// Inside a dynamically tagged object (facet_value::Value object).
75    InDynamicObject {
76        remaining_entries: u64,
77        expecting_key: bool,
78    },
79}
80
81/// Postcard parser for Tier-0 and Tier-2 deserialization.
82///
83/// For Tier-0, the parser relies on `hint_struct_fields` to know how many fields
84/// to expect in structs. Sequences are length-prefixed in the wire format.
85pub struct PostcardParser<'de> {
86    input: &'de [u8],
87    pos: usize,
88    max_collection_elements: u64,
89    /// Stack of parser states for nested structures.
90    state_stack: Vec<ParserState>,
91    /// Peeked event (for `peek_event`).
92    peeked: Option<ParseEvent<'de>>,
93    /// Pending struct field count from `hint_struct_fields`.
94    pending_struct_fields: Option<usize>,
95    /// Pending scalar type hint from `hint_scalar_type`.
96    pending_scalar_type: Option<ScalarTypeHint>,
97    /// Pending sequence flag from `hint_sequence`.
98    pending_sequence: bool,
99    /// Pending byte sequence flag from `hint_byte_sequence`.
100    pending_byte_sequence: bool,
101    /// Pending remaining-bytes flag from `hint_remaining_byte_sequence`.
102    pending_remaining_bytes: bool,
103    /// Pending fixed-size array length from `hint_array`.
104    pending_array: Option<usize>,
105    /// Pending option flag from `hint_option`.
106    pending_option: bool,
107    /// Pending enum variant metadata from `hint_enum`.
108    pending_enum: Option<Vec<VariantMeta>>,
109    /// Pending opaque scalar type from `hint_opaque_scalar`.
110    pending_opaque: Option<OpaqueScalarHint>,
111    /// Pending map flag from `hint_map`.
112    pending_map: bool,
113    /// Pending dynamic value tag from `hint_dynamic_value`.
114    pending_dynamic: bool,
115}
116
117/// Information about an opaque scalar type for format-specific handling.
118#[derive(Debug, Clone)]
119struct OpaqueScalarHint {
120    type_identifier: &'static str,
121    /// True if the inner type is f32 (for OrderedFloat/NotNan)
122    inner_is_f32: bool,
123}
124
125impl<'de> PostcardParser<'de> {
126    /// Create a new postcard parser from input bytes.
127    pub const fn new(input: &'de [u8]) -> Self {
128        Self::with_limits(input, DEFAULT_MAX_COLLECTION_ELEMENTS)
129    }
130
131    /// Create a new postcard parser with custom safety limits.
132    pub const fn with_limits(input: &'de [u8], max_collection_elements: u64) -> Self {
133        Self {
134            input,
135            pos: 0,
136            max_collection_elements,
137            state_stack: Vec::new(),
138            peeked: None,
139            pending_struct_fields: None,
140            pending_scalar_type: None,
141            pending_sequence: false,
142            pending_byte_sequence: false,
143            pending_remaining_bytes: false,
144            pending_array: None,
145            pending_option: false,
146            pending_enum: None,
147            pending_opaque: None,
148            pending_map: false,
149            pending_dynamic: false,
150        }
151    }
152
153    /// Read a single byte, advancing position.
154    fn read_byte(&mut self) -> Result<u8, ParseError> {
155        if self.pos >= self.input.len() {
156            return Err(error_from_code(codes::UNEXPECTED_EOF, self.pos));
157        }
158        let byte = self.input[self.pos];
159        self.pos += 1;
160        Ok(byte)
161    }
162
163    /// Read a varint (LEB128 encoded unsigned integer).
164    fn read_varint(&mut self) -> Result<u64, ParseError> {
165        let mut result: u64 = 0;
166        let mut shift: u32 = 0;
167
168        loop {
169            let byte = self.read_byte()?;
170            let data = (byte & 0x7F) as u64;
171
172            if shift >= 64 {
173                return Err(error_from_code(codes::VARINT_OVERFLOW, self.pos));
174            }
175
176            result |= data << shift;
177            shift += 7;
178
179            if (byte & 0x80) == 0 {
180                return Ok(result);
181            }
182        }
183    }
184
185    fn validate_collection_count(&self, count: u64) -> Result<(), ParseError> {
186        if count <= self.max_collection_elements {
187            return Ok(());
188        }
189
190        Err(ParseError::new(
191            Span::new(self.pos, 1),
192            DeserializeErrorKind::InvalidValue {
193                message: format!(
194                    "collection length {} exceeds maximum {}",
195                    count, self.max_collection_elements
196                )
197                .into(),
198            },
199        ))
200    }
201
202    /// Read a signed varint (ZigZag + LEB128).
203    fn read_signed_varint(&mut self) -> Result<i64, ParseError> {
204        let unsigned = self.read_varint()?;
205        // ZigZag decode: (n >> 1) ^ -(n & 1)
206        let decoded = ((unsigned >> 1) as i64) ^ -((unsigned & 1) as i64);
207        Ok(decoded)
208    }
209
210    /// Read a varint for u128 (LEB128 encoded, up to 19 bytes).
211    fn read_varint_u128(&mut self) -> Result<u128, ParseError> {
212        let mut result: u128 = 0;
213        let mut shift: u32 = 0;
214
215        loop {
216            let byte = self.read_byte()?;
217            let data = (byte & 0x7F) as u128;
218
219            if shift >= 128 {
220                return Err(error_from_code(codes::VARINT_OVERFLOW, self.pos));
221            }
222
223            result |= data << shift;
224            shift += 7;
225
226            if (byte & 0x80) == 0 {
227                return Ok(result);
228            }
229        }
230    }
231
232    /// Read a signed varint for i128 (ZigZag + LEB128).
233    fn read_signed_varint_i128(&mut self) -> Result<i128, ParseError> {
234        let unsigned = self.read_varint_u128()?;
235        // ZigZag decode: (n >> 1) ^ -(n & 1)
236        let decoded = ((unsigned >> 1) as i128) ^ -((unsigned & 1) as i128);
237        Ok(decoded)
238    }
239
240    /// Read N bytes as a slice.
241    fn read_bytes(&mut self, len: usize) -> Result<&'de [u8], ParseError> {
242        let end = self
243            .pos
244            .checked_add(len)
245            .ok_or_else(|| error_from_code(codes::UNEXPECTED_EOF, self.pos))?;
246        if end > self.input.len() {
247            return Err(error_from_code(codes::UNEXPECTED_EOF, self.pos));
248        }
249        let bytes = &self.input[self.pos..end];
250        self.pos = end;
251        Ok(bytes)
252    }
253
254    /// Get the current parser state (top of stack or Ready).
255    fn current_state(&self) -> &ParserState {
256        self.state_stack.last().unwrap_or(&ParserState::Ready)
257    }
258
259    /// Generate the next event based on current state.
260    fn generate_next_event(&mut self) -> Result<ParseEvent<'de>, ParseError> {
261        // Check if we have a pending option hint
262        if self.pending_option {
263            self.pending_option = false;
264            let discriminant = self.read_byte()?;
265            match discriminant {
266                0x00 => {
267                    return Ok(self.event(ParseEventKind::Scalar(ScalarValue::Null)));
268                }
269                0x01 => {
270                    // Some(value) - consumed the discriminant. The deserializer will peek to check
271                    // if it's None, see this is not Null, and then call deserialize_into for the value.
272                    // Return a placeholder event (like OrderedField) to signal "not None".
273                    // The deserializer will then call hint + expect for the inner value.
274                    return Ok(self.event(ParseEventKind::OrderedField));
275                }
276                _ => {
277                    return Err(ParseError::new(
278                        Span::new(self.pos - 1, 1),
279                        DeserializeErrorKind::InvalidValue {
280                            message: format!("invalid Option discriminant: {}", discriminant)
281                                .into(),
282                        },
283                    ));
284                }
285            }
286        }
287
288        // Check if we have a pending dynamic value hint (tagged dynamic values)
289        if self.pending_dynamic {
290            self.pending_dynamic = false;
291            return self.parse_dynamic_tag_event();
292        }
293
294        // Check if we have a pending enum hint
295        if let Some(variants) = self.pending_enum.take() {
296            let variant_index = self.read_varint()? as usize;
297            if variant_index >= variants.len() {
298                return Err(ParseError::new(
299                    Span::new(self.pos, 1),
300                    DeserializeErrorKind::InvalidValue {
301                        message: format!(
302                            "enum variant index {} out of range (max {})",
303                            variant_index,
304                            variants.len() - 1
305                        )
306                        .into(),
307                    },
308                ));
309            }
310            let variant = &variants[variant_index];
311            // Push InEnum state to emit StructStart, FieldKey, content, StructEnd sequence
312            self.state_stack.push(ParserState::InEnum {
313                variant_name: variant.name.clone(),
314                variant_kind: variant.kind,
315                variant_field_count: variant.field_count,
316                field_key_emitted: false,
317                wrapper_start_emitted: false,
318                wrapper_end_emitted: false,
319            });
320            return Ok(self.event(ParseEventKind::StructStart(ContainerKind::Object)));
321        }
322
323        // Check if we have a pending opaque scalar hint (format-specific binary encoding)
324        if let Some(opaque) = self.pending_opaque.take() {
325            return self.parse_opaque_scalar(opaque);
326        }
327
328        // Check if we have a pending trailing bytes hint (consume rest of input as bytes)
329        if self.pending_remaining_bytes {
330            self.pending_remaining_bytes = false;
331            let bytes = &self.input[self.pos..];
332            self.pos = self.input.len();
333            return Ok(
334                self.event(ParseEventKind::Scalar(ScalarValue::Bytes(Cow::Borrowed(
335                    bytes,
336                )))),
337            );
338        }
339
340        // Check if we have a pending scalar type hint
341        if let Some(hint) = self.pending_scalar_type.take() {
342            return self.parse_scalar_with_hint(hint);
343        }
344
345        // Check if we have a pending sequence hint (variable-length, reads count from wire)
346        if self.pending_sequence {
347            self.pending_sequence = false;
348            let count = self.read_varint()?;
349            self.validate_collection_count(count)?;
350            self.state_stack.push(ParserState::InSequence {
351                remaining_elements: count,
352            });
353            return Ok(self.event(ParseEventKind::SequenceStart(ContainerKind::Array)));
354        }
355
356        // Check if we have a pending byte sequence hint (bulk read for Vec<u8>)
357        if self.pending_byte_sequence {
358            self.pending_byte_sequence = false;
359            let bytes = self.parse_bytes()?;
360            return Ok(
361                self.event(ParseEventKind::Scalar(ScalarValue::Bytes(Cow::Borrowed(
362                    bytes,
363                )))),
364            );
365        }
366
367        // Check if we have a pending fixed-size array hint (length known from type, no wire prefix)
368        if let Some(len) = self.pending_array.take() {
369            self.state_stack.push(ParserState::InSequence {
370                remaining_elements: len as u64,
371            });
372            return Ok(self.event(ParseEventKind::SequenceStart(ContainerKind::Array)));
373        }
374
375        // Check if we have a pending struct hint
376        if let Some(num_fields) = self.pending_struct_fields.take() {
377            self.state_stack.push(ParserState::InStruct {
378                remaining_fields: num_fields,
379            });
380            return Ok(self.event(ParseEventKind::StructStart(ContainerKind::Object)));
381        }
382
383        // Check if we have a pending map hint (maps are length-prefixed sequences of key-value pairs)
384        if self.pending_map {
385            self.pending_map = false;
386            let count = self.read_varint()?;
387            self.validate_collection_count(count)?;
388            self.state_stack.push(ParserState::InMap {
389                remaining_entries: count,
390            });
391            return Ok(self.event(ParseEventKind::SequenceStart(ContainerKind::Array)));
392        }
393
394        // Check current state
395        match self.current_state().clone() {
396            ParserState::Ready => {
397                // At top level without a hint - error
398                Err(ParseError::new(
399                    Span::new(self.pos, 1),
400                    DeserializeErrorKind::InvalidValue {
401                        message: "postcard parser needs type hints (use hint_scalar_type, hint_struct_fields, or hint_sequence)".into(),
402                    },
403                ))
404            }
405            ParserState::InStruct { remaining_fields } => {
406                if remaining_fields == 0 {
407                    // Struct complete
408                    self.state_stack.pop();
409                    Ok(self.event(ParseEventKind::StructEnd))
410                } else {
411                    // More fields to go - emit OrderedField and decrement
412                    if let Some(ParserState::InStruct { remaining_fields }) =
413                        self.state_stack.last_mut()
414                    {
415                        *remaining_fields -= 1;
416                    }
417                    Ok(self.event(ParseEventKind::OrderedField))
418                }
419            }
420            ParserState::InSequence { remaining_elements } => {
421                if remaining_elements == 0 {
422                    // Sequence complete
423                    self.state_stack.pop();
424                    Ok(self.event(ParseEventKind::SequenceEnd))
425                } else {
426                    // More elements remaining. Return OrderedField as a placeholder to indicate
427                    // "not end yet". The deserializer will then call hint + expect for the next element.
428                    // Decrement the counter after returning the placeholder.
429                    if let Some(ParserState::InSequence { remaining_elements }) =
430                        self.state_stack.last_mut()
431                    {
432                        *remaining_elements -= 1;
433                    }
434                    Ok(self.event(ParseEventKind::OrderedField))
435                }
436            }
437            ParserState::InEnum {
438                variant_name,
439                variant_kind,
440                variant_field_count,
441                field_key_emitted,
442                wrapper_start_emitted,
443                wrapper_end_emitted,
444            } => {
445                use facet_core::StructKind;
446
447                if !field_key_emitted {
448                    // Step 1: Emit the FieldKey with the variant name
449                    if let Some(ParserState::InEnum {
450                        field_key_emitted, ..
451                    }) = self.state_stack.last_mut()
452                    {
453                        *field_key_emitted = true;
454                    }
455                    Ok(self.event(ParseEventKind::FieldKey(FieldKey::new(
456                        Cow::Owned(variant_name.clone()),
457                        FieldLocationHint::KeyValue,
458                    ))))
459                } else if !wrapper_start_emitted {
460                    // Step 2: After FieldKey, emit wrapper start (if needed)
461                    match variant_kind {
462                        StructKind::Unit => {
463                            // Unit variant - no wrapper, skip directly to StructEnd
464                            self.state_stack.pop();
465                            Ok(self.event(ParseEventKind::StructEnd))
466                        }
467                        StructKind::Tuple | StructKind::TupleStruct => {
468                            // Check if it's a newtype (single-field) or multi-field tuple
469                            if variant_field_count == 1 {
470                                // Newtype variant - no wrapper, content consumed directly
471                                // Mark wrapper as emitted so we skip directly to final StructEnd
472                                if let Some(ParserState::InEnum {
473                                    wrapper_start_emitted,
474                                    wrapper_end_emitted,
475                                    ..
476                                }) = self.state_stack.last_mut()
477                                {
478                                    *wrapper_start_emitted = true;
479                                    *wrapper_end_emitted = true; // Skip wrapper end emission
480                                }
481                                // Recursively call to get the next event (likely a scalar hint response)
482                                self.generate_next_event()
483                            } else {
484                                // Multi-field tuple variant - emit SequenceStart and push InSequence state
485                                // But unlike regular sequences, tuple enum variants don't use OrderedField placeholders
486                                // The deserializer calls deserialize_into directly for each field
487                                // So we DON'T push InSequence - we track manually via wrapper_end_emitted
488                                if let Some(ParserState::InEnum {
489                                    wrapper_start_emitted,
490                                    ..
491                                }) = self.state_stack.last_mut()
492                                {
493                                    *wrapper_start_emitted = true;
494                                }
495                                Ok(self.event(ParseEventKind::SequenceStart(ContainerKind::Array)))
496                            }
497                        }
498                        StructKind::Struct => {
499                            // Struct variant - mark wrapper start emitted and push InStruct state
500                            // The InStruct state will emit OrderedField events for each field
501                            // (postcard encodes struct fields in order without names)
502                            if let Some(ParserState::InEnum {
503                                wrapper_start_emitted,
504                                ..
505                            }) = self.state_stack.last_mut()
506                            {
507                                *wrapper_start_emitted = true;
508                            }
509                            // Get the field count from the variant
510                            let field_count = if let ParserState::InEnum {
511                                variant_field_count,
512                                ..
513                            } = self.current_state()
514                            {
515                                *variant_field_count
516                            } else {
517                                0
518                            };
519                            self.state_stack.push(ParserState::InStruct {
520                                remaining_fields: field_count,
521                            });
522                            Ok(self.event(ParseEventKind::StructStart(ContainerKind::Object)))
523                        }
524                    }
525                } else if !wrapper_end_emitted {
526                    // Step 3: Emit wrapper end for multi-field variants
527                    match variant_kind {
528                        StructKind::Unit => {
529                            // Already handled above
530                            unreachable!()
531                        }
532                        StructKind::Tuple | StructKind::TupleStruct => {
533                            // For multi-field tuples, emit SequenceEnd
534                            if variant_field_count > 1 {
535                                if let Some(ParserState::InEnum {
536                                    wrapper_end_emitted,
537                                    ..
538                                }) = self.state_stack.last_mut()
539                                {
540                                    *wrapper_end_emitted = true;
541                                }
542                                Ok(self.event(ParseEventKind::SequenceEnd))
543                            } else {
544                                // Newtype - already marked wrapper_end_emitted=true, skip to final StructEnd
545                                self.state_stack.pop();
546                                Ok(self.event(ParseEventKind::StructEnd))
547                            }
548                        }
549                        StructKind::Struct => {
550                            // Struct variants use InStruct which already popped, so we're ready for final StructEnd
551                            self.state_stack.pop();
552                            Ok(self.event(ParseEventKind::StructEnd))
553                        }
554                    }
555                } else {
556                    // Step 4: Emit final outer StructEnd
557                    // This is reached after wrapper end has been emitted
558                    self.state_stack.pop();
559                    Ok(self.event(ParseEventKind::StructEnd))
560                }
561            }
562            ParserState::InMap { remaining_entries } => {
563                if remaining_entries == 0 {
564                    // Map complete
565                    self.state_stack.pop();
566                    Ok(self.event(ParseEventKind::SequenceEnd))
567                } else {
568                    // More entries remaining. Return OrderedField as a placeholder to indicate
569                    // "not end yet". The deserializer will call hint + expect for key and value.
570                    // Decrement the counter after returning the placeholder.
571                    if let Some(ParserState::InMap { remaining_entries }) =
572                        self.state_stack.last_mut()
573                    {
574                        *remaining_entries -= 1;
575                    }
576                    Ok(self.event(ParseEventKind::OrderedField))
577                }
578            }
579            ParserState::InDynamicArray { remaining_elements } => {
580                if remaining_elements == 0 {
581                    self.state_stack.pop();
582                    Ok(self.event(ParseEventKind::SequenceEnd))
583                } else {
584                    self.parse_dynamic_tag_event()
585                }
586            }
587            ParserState::InDynamicObject {
588                remaining_entries,
589                expecting_key,
590            } => {
591                if remaining_entries == 0 {
592                    self.state_stack.pop();
593                    Ok(self.event(ParseEventKind::StructEnd))
594                } else if expecting_key {
595                    let key = self.parse_string()?;
596                    if let Some(ParserState::InDynamicObject { expecting_key, .. }) =
597                        self.state_stack.last_mut()
598                    {
599                        *expecting_key = false;
600                    }
601                    Ok(self.event(ParseEventKind::FieldKey(FieldKey::new(
602                        Cow::Borrowed(key),
603                        FieldLocationHint::KeyValue,
604                    ))))
605                } else {
606                    self.parse_dynamic_tag_event()
607                }
608            }
609        }
610    }
611
612    /// Parse a scalar value with the given type hint.
613    fn parse_scalar_with_hint(
614        &mut self,
615        hint: ScalarTypeHint,
616    ) -> Result<ParseEvent<'de>, ParseError> {
617        let scalar = match hint {
618            ScalarTypeHint::Bool => {
619                let val = self.parse_bool()?;
620                ScalarValue::Bool(val)
621            }
622            ScalarTypeHint::U8 => {
623                let val = self.parse_u8()?;
624                ScalarValue::U64(val as u64)
625            }
626            ScalarTypeHint::U16 => {
627                let val = self.parse_u16()?;
628                ScalarValue::U64(val as u64)
629            }
630            ScalarTypeHint::U32 => {
631                let val = self.parse_u32()?;
632                ScalarValue::U64(val as u64)
633            }
634            ScalarTypeHint::U64 => {
635                let val = self.parse_u64()?;
636                ScalarValue::U64(val)
637            }
638            ScalarTypeHint::U128 => {
639                let val = self.parse_u128()?;
640                ScalarValue::U128(val)
641            }
642            ScalarTypeHint::Usize => {
643                // usize is encoded as varint, decode as u64
644                let val = self.parse_u64()?;
645                ScalarValue::U64(val)
646            }
647            ScalarTypeHint::I8 => {
648                let val = self.parse_i8()?;
649                ScalarValue::I64(val as i64)
650            }
651            ScalarTypeHint::I16 => {
652                let val = self.parse_i16()?;
653                ScalarValue::I64(val as i64)
654            }
655            ScalarTypeHint::I32 => {
656                let val = self.parse_i32()?;
657                ScalarValue::I64(val as i64)
658            }
659            ScalarTypeHint::I64 => {
660                let val = self.parse_i64()?;
661                ScalarValue::I64(val)
662            }
663            ScalarTypeHint::I128 => {
664                let val = self.parse_i128()?;
665                ScalarValue::I128(val)
666            }
667            ScalarTypeHint::Isize => {
668                // isize is encoded as zigzag varint, decode as i64
669                let val = self.parse_i64()?;
670                ScalarValue::I64(val)
671            }
672            ScalarTypeHint::F32 => {
673                let val = self.parse_f32()?;
674                ScalarValue::F64(val as f64)
675            }
676            ScalarTypeHint::F64 => {
677                let val = self.parse_f64()?;
678                ScalarValue::F64(val)
679            }
680            ScalarTypeHint::String => {
681                let val = self.parse_string()?;
682                ScalarValue::Str(Cow::Borrowed(val))
683            }
684            ScalarTypeHint::Bytes => {
685                let val = self.parse_bytes()?;
686                ScalarValue::Bytes(Cow::Borrowed(val))
687            }
688            ScalarTypeHint::Char => {
689                // Per postcard spec: char is encoded as UTF-8 string (length-prefixed UTF-8 bytes)
690                let s = self.parse_string()?;
691                // Validate it's exactly one char
692                let mut chars = s.chars();
693                let c = chars.next().ok_or_else(|| {
694                    ParseError::new(
695                        Span::new(self.pos, 1),
696                        DeserializeErrorKind::InvalidValue {
697                            message: "empty string for char".into(),
698                        },
699                    )
700                })?;
701                if chars.next().is_some() {
702                    return Err(ParseError::new(
703                        Span::new(self.pos, 1),
704                        DeserializeErrorKind::InvalidValue {
705                            message: "string contains more than one char".into(),
706                        },
707                    ));
708                }
709                // Represent as string since ScalarValue doesn't have Char
710                ScalarValue::Str(Cow::Owned(c.to_string()))
711            }
712        };
713        Ok(self.event(ParseEventKind::Scalar(scalar)))
714    }
715
716    /// Parse an opaque scalar value with format-specific binary encoding.
717    ///
718    /// This handles types like UUID (16 raw bytes), ULID (16 raw bytes),
719    /// OrderedFloat (raw float bytes), etc. that have efficient binary
720    /// representations in postcard.
721    fn parse_opaque_scalar(
722        &mut self,
723        opaque: OpaqueScalarHint,
724    ) -> Result<ParseEvent<'de>, ParseError> {
725        let scalar = match opaque.type_identifier {
726            // UUID/ULID: 16 raw bytes (no length prefix)
727            "Uuid" | "Ulid" => {
728                let bytes = self.read_fixed_bytes(16)?;
729                ScalarValue::Bytes(Cow::Borrowed(bytes))
730            }
731            // OrderedFloat/NotNan: raw float bytes (size depends on inner type)
732            // We handle both f32 and f64 variants by checking the shape's inner field
733            "OrderedFloat" | "NotNan" => {
734                // Check inner shape to determine f32 vs f64
735                if opaque.inner_is_f32 {
736                    let val = self.parse_f32()?;
737                    ScalarValue::F64(val as f64)
738                } else {
739                    // Default to f64
740                    let val = self.parse_f64()?;
741                    ScalarValue::F64(val)
742                }
743            }
744            // Camino Utf8PathBuf/Utf8Path: regular string
745            "Utf8PathBuf" | "Utf8Path" => {
746                let val = self.parse_string()?;
747                ScalarValue::Str(Cow::Borrowed(val))
748            }
749            // Chrono types: RFC3339 strings
750            "DateTime<Utc>"
751            | "DateTime<Local>"
752            | "DateTime<FixedOffset>"
753            | "NaiveDateTime"
754            | "NaiveDate"
755            | "NaiveTime" => {
756                let val = self.parse_string()?;
757                ScalarValue::Str(Cow::Borrowed(val))
758            }
759            // Jiff types: RFC3339/ISO8601 strings
760            "Timestamp" | "Zoned" | "civil::DateTime" | "civil::Date" | "civil::Time" | "Span"
761            | "SignedDuration" => {
762                let val = self.parse_string()?;
763                ScalarValue::Str(Cow::Borrowed(val))
764            }
765            // Time crate types: RFC3339 strings
766            "UtcDateTime" | "OffsetDateTime" | "PrimitiveDateTime" | "Date" | "Time" => {
767                let val = self.parse_string()?;
768                ScalarValue::Str(Cow::Borrowed(val))
769            }
770            // Unknown opaque type - shouldn't happen (hint_opaque_scalar returned true)
771            _ => {
772                return Err(ParseError::new(
773                    Span::new(self.pos, 1),
774                    DeserializeErrorKind::InvalidValue {
775                        message: format!("unsupported opaque type: {}", opaque.type_identifier)
776                            .into(),
777                    },
778                ));
779            }
780        };
781        Ok(self.event(ParseEventKind::Scalar(scalar)))
782    }
783
784    /// Read exactly N bytes from input without length prefix.
785    fn read_fixed_bytes(&mut self, len: usize) -> Result<&'de [u8], ParseError> {
786        let end = self
787            .pos
788            .checked_add(len)
789            .ok_or_else(|| error_from_code(codes::UNEXPECTED_EOF, self.pos))?;
790        if end > self.input.len() {
791            return Err(error_from_code(codes::UNEXPECTED_EOF, self.pos));
792        }
793        let bytes = &self.input[self.pos..end];
794        self.pos = end;
795        Ok(bytes)
796    }
797
798    /// Parse a boolean value.
799    pub fn parse_bool(&mut self) -> Result<bool, ParseError> {
800        let byte = self.read_byte()?;
801        match byte {
802            0 => Ok(false),
803            1 => Ok(true),
804            _ => Err(error_from_code(codes::INVALID_BOOL, self.pos - 1)),
805        }
806    }
807
808    /// Parse an unsigned 8-bit integer.
809    pub fn parse_u8(&mut self) -> Result<u8, ParseError> {
810        self.read_byte()
811    }
812
813    /// Parse an unsigned 16-bit integer (varint).
814    pub fn parse_u16(&mut self) -> Result<u16, ParseError> {
815        let val = self.read_varint()?;
816        Ok(val as u16)
817    }
818
819    /// Parse an unsigned 32-bit integer (varint).
820    pub fn parse_u32(&mut self) -> Result<u32, ParseError> {
821        let val = self.read_varint()?;
822        Ok(val as u32)
823    }
824
825    /// Parse an unsigned 64-bit integer (varint).
826    pub fn parse_u64(&mut self) -> Result<u64, ParseError> {
827        self.read_varint()
828    }
829
830    /// Parse an unsigned 128-bit integer (varint).
831    pub fn parse_u128(&mut self) -> Result<u128, ParseError> {
832        self.read_varint_u128()
833    }
834
835    /// Parse a signed 8-bit integer (single byte, two's complement).
836    pub fn parse_i8(&mut self) -> Result<i8, ParseError> {
837        // i8 is encoded as a single byte in two's complement form (not varint)
838        let byte = self.read_byte()?;
839        Ok(byte as i8)
840    }
841
842    /// Parse a signed 16-bit integer (zigzag varint).
843    pub fn parse_i16(&mut self) -> Result<i16, ParseError> {
844        let val = self.read_signed_varint()?;
845        Ok(val as i16)
846    }
847
848    /// Parse a signed 32-bit integer (zigzag varint).
849    pub fn parse_i32(&mut self) -> Result<i32, ParseError> {
850        let val = self.read_signed_varint()?;
851        Ok(val as i32)
852    }
853
854    /// Parse a signed 64-bit integer (zigzag varint).
855    pub fn parse_i64(&mut self) -> Result<i64, ParseError> {
856        self.read_signed_varint()
857    }
858
859    /// Parse a signed 128-bit integer (zigzag varint).
860    pub fn parse_i128(&mut self) -> Result<i128, ParseError> {
861        self.read_signed_varint_i128()
862    }
863
864    /// Parse a 32-bit float (little-endian).
865    pub fn parse_f32(&mut self) -> Result<f32, ParseError> {
866        let bytes = self.read_bytes(4)?;
867        Ok(f32::from_le_bytes(bytes.try_into().unwrap()))
868    }
869
870    /// Parse a 64-bit float (little-endian).
871    pub fn parse_f64(&mut self) -> Result<f64, ParseError> {
872        let bytes = self.read_bytes(8)?;
873        Ok(f64::from_le_bytes(bytes.try_into().unwrap()))
874    }
875
876    /// Parse a string (varint length + UTF-8 bytes).
877    pub fn parse_string(&mut self) -> Result<&'de str, ParseError> {
878        let len = self.read_varint()? as usize;
879        let bytes = self.read_bytes(len)?;
880        core::str::from_utf8(bytes).map_err(|_| {
881            let mut context = [0u8; 16];
882            let context_len = len.min(16);
883            context[..context_len].copy_from_slice(&bytes[..context_len]);
884            ParseError::new(
885                Span::new(self.pos - len, len),
886                DeserializeErrorKind::InvalidUtf8 {
887                    context,
888                    context_len: context_len as u8,
889                },
890            )
891        })
892    }
893
894    /// Parse bytes (varint length + raw bytes).
895    pub fn parse_bytes(&mut self) -> Result<&'de [u8], ParseError> {
896        let len = self.read_varint()? as usize;
897        self.read_bytes(len)
898    }
899
900    /// Begin parsing a sequence, returning the element count.
901    pub fn begin_sequence(&mut self) -> Result<u64, ParseError> {
902        let count = self.read_varint()?;
903        self.validate_collection_count(count)?;
904        self.state_stack.push(ParserState::InSequence {
905            remaining_elements: count,
906        });
907        Ok(count)
908    }
909
910    fn parse_dynamic_tag_event(&mut self) -> Result<ParseEvent<'de>, ParseError> {
911        // If we're inside a dynamic object and expecting a value, advance entry tracking now.
912        if let Some(ParserState::InDynamicObject {
913            remaining_entries,
914            expecting_key,
915        }) = self.state_stack.last_mut()
916            && !*expecting_key
917        {
918            *remaining_entries = remaining_entries.saturating_sub(1);
919            *expecting_key = true;
920        }
921
922        if let Some(ParserState::InDynamicArray { remaining_elements }) =
923            self.state_stack.last_mut()
924        {
925            *remaining_elements = remaining_elements.saturating_sub(1);
926        }
927
928        let tag = self.read_byte()?;
929        match tag {
930            0 => Ok(self.event(ParseEventKind::Scalar(ScalarValue::Null))),
931            1 => self.parse_scalar_with_hint(ScalarTypeHint::Bool),
932            2 => self.parse_scalar_with_hint(ScalarTypeHint::I64),
933            3 => self.parse_scalar_with_hint(ScalarTypeHint::U64),
934            4 => self.parse_scalar_with_hint(ScalarTypeHint::F64),
935            5 => self.parse_scalar_with_hint(ScalarTypeHint::String),
936            6 => self.parse_scalar_with_hint(ScalarTypeHint::Bytes),
937            7 => {
938                let count = self.read_varint()?;
939                self.validate_collection_count(count)?;
940                self.state_stack.push(ParserState::InDynamicArray {
941                    remaining_elements: count,
942                });
943                Ok(self.event(ParseEventKind::SequenceStart(ContainerKind::Array)))
944            }
945            8 => {
946                let count = self.read_varint()?;
947                self.validate_collection_count(count)?;
948                self.state_stack.push(ParserState::InDynamicObject {
949                    remaining_entries: count,
950                    expecting_key: true,
951                });
952                Ok(self.event(ParseEventKind::StructStart(ContainerKind::Object)))
953            }
954            9 => self.parse_scalar_with_hint(ScalarTypeHint::String),
955            _ => Err(ParseError::new(
956                Span::new(self.pos.saturating_sub(1), 1),
957                DeserializeErrorKind::InvalidValue {
958                    message: format!("invalid dynamic value tag: {}", tag).into(),
959                },
960            )),
961        }
962    }
963}
964
965impl<'de> PostcardParser<'de> {
966    /// Create an event with the current span.
967    #[inline]
968    fn event(&self, kind: ParseEventKind<'de>) -> ParseEvent<'de> {
969        ParseEvent::new(kind, Span::new(self.pos, 1))
970    }
971}
972
973impl<'de> FormatParser<'de> for PostcardParser<'de> {
974    fn next_event(&mut self) -> Result<Option<ParseEvent<'de>>, ParseError> {
975        // Return peeked event if available
976        if let Some(event) = self.peeked.take() {
977            return Ok(Some(event));
978        }
979        Ok(Some(self.generate_next_event()?))
980    }
981
982    fn peek_event(&mut self) -> Result<Option<ParseEvent<'de>>, ParseError> {
983        if self.peeked.is_none() {
984            self.peeked = Some(self.generate_next_event()?);
985        }
986        Ok(self.peeked.clone())
987    }
988
989    fn skip_value(&mut self) -> Result<(), ParseError> {
990        // For non-self-describing formats, skipping is complex because
991        // we don't know the type/size of the value.
992        Err(ParseError::new(
993            Span::new(self.pos, 1),
994            DeserializeErrorKind::InvalidValue {
995                message: "skip_value not supported for postcard (non-self-describing)".into(),
996            },
997        ))
998    }
999
1000    fn current_span(&self) -> Option<Span> {
1001        Some(Span::new(self.pos, 1))
1002    }
1003
1004    fn format_namespace(&self) -> Option<&'static str> {
1005        Some("postcard")
1006    }
1007
1008    fn save(&mut self) -> SavePoint {
1009        // Postcard doesn't support save/restore (non-self-describing format)
1010        // The solver can't work with positional formats anyway
1011        unimplemented!("save/restore not supported for postcard (non-self-describing)")
1012    }
1013
1014    fn restore(&mut self, _save_point: SavePoint) {
1015        // Postcard doesn't support save/restore (non-self-describing format)
1016        unimplemented!("save/restore not supported for postcard (non-self-describing)")
1017    }
1018
1019    fn is_self_describing(&self) -> bool {
1020        false
1021    }
1022
1023    fn hint_struct_fields(&mut self, num_fields: usize) {
1024        self.pending_struct_fields = Some(num_fields);
1025        // Clear any peeked OrderedField placeholder for sequences
1026        if self
1027            .peeked
1028            .as_ref()
1029            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1030        {
1031            self.peeked = None;
1032        }
1033    }
1034
1035    fn hint_scalar_type(&mut self, hint: ScalarTypeHint) {
1036        self.pending_scalar_type = Some(hint);
1037        // Clear any peeked OrderedField placeholder for sequences
1038        if self
1039            .peeked
1040            .as_ref()
1041            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1042        {
1043            self.peeked = None;
1044        }
1045    }
1046
1047    fn hint_sequence(&mut self) {
1048        self.pending_sequence = true;
1049        // Clear any peeked OrderedField placeholder
1050        if self
1051            .peeked
1052            .as_ref()
1053            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1054        {
1055            self.peeked = None;
1056        }
1057    }
1058
1059    fn hint_byte_sequence(&mut self) -> bool {
1060        self.pending_byte_sequence = true;
1061        // Clear any peeked OrderedField placeholder
1062        if self
1063            .peeked
1064            .as_ref()
1065            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1066        {
1067            self.peeked = None;
1068        }
1069        true // Postcard supports bulk byte reading
1070    }
1071
1072    fn hint_remaining_byte_sequence(&mut self) -> bool {
1073        self.pending_remaining_bytes = true;
1074        if self
1075            .peeked
1076            .as_ref()
1077            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1078        {
1079            self.peeked = None;
1080        }
1081        true
1082    }
1083
1084    fn hint_array(&mut self, len: usize) {
1085        self.pending_array = Some(len);
1086        // Clear any peeked OrderedField placeholder
1087        if self
1088            .peeked
1089            .as_ref()
1090            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1091        {
1092            self.peeked = None;
1093        }
1094    }
1095
1096    fn hint_option(&mut self) {
1097        self.pending_option = true;
1098        // Clear any peeked OrderedField placeholder
1099        if self
1100            .peeked
1101            .as_ref()
1102            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1103        {
1104            self.peeked = None;
1105        }
1106    }
1107
1108    fn hint_enum(&mut self, variants: &[EnumVariantHint]) {
1109        // Store variant metadata, converting to owned strings to avoid lifetime issues.
1110        let metas: Vec<VariantMeta> = variants
1111            .iter()
1112            .map(|v| VariantMeta {
1113                name: v.name.to_string(),
1114                kind: v.kind,
1115                field_count: v.field_count,
1116            })
1117            .collect();
1118        self.pending_enum = Some(metas);
1119        // Clear any peeked OrderedField placeholder for sequences
1120        if self
1121            .peeked
1122            .as_ref()
1123            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1124        {
1125            self.peeked = None;
1126        }
1127    }
1128
1129    fn hint_map(&mut self) {
1130        self.pending_map = true;
1131        // Clear any peeked OrderedField placeholder
1132        if self
1133            .peeked
1134            .as_ref()
1135            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1136        {
1137            self.peeked = None;
1138        }
1139    }
1140
1141    fn hint_dynamic_value(&mut self) {
1142        // Clear any peeked OrderedField placeholder (it's just a "not done yet" signal)
1143        if self
1144            .peeked
1145            .as_ref()
1146            .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1147        {
1148            self.peeked = None;
1149        }
1150        // If something else is peeked, don't override it
1151        if self.peeked.is_some() {
1152            return;
1153        }
1154        self.pending_dynamic = true;
1155    }
1156
1157    fn hint_opaque_scalar(
1158        &mut self,
1159        type_identifier: &'static str,
1160        shape: &'static facet_core::Shape,
1161    ) -> bool {
1162        // Check if we handle this type specially in postcard
1163        let handled = matches!(
1164            type_identifier,
1165            // UUID/ULID: 16 raw bytes
1166            "Uuid" | "Ulid"
1167            // OrderedFloat/NotNan: raw float bytes (size determined by inner type)
1168            | "OrderedFloat" | "NotNan"
1169            // Camino paths: strings
1170            | "Utf8PathBuf" | "Utf8Path"
1171            // Chrono types: RFC3339 strings
1172            | "DateTime<Utc>" | "DateTime<Local>" | "DateTime<FixedOffset>"
1173            | "NaiveDateTime" | "NaiveDate" | "NaiveTime"
1174            // Jiff types: RFC3339/ISO8601 strings
1175            | "Timestamp" | "Zoned" | "civil::DateTime" | "civil::Date" | "civil::Time"
1176            | "Span" | "SignedDuration"
1177            // Time crate types: RFC3339 strings
1178            | "UtcDateTime" | "OffsetDateTime" | "PrimitiveDateTime" | "Date" | "Time"
1179        );
1180
1181        if handled {
1182            // Check inner shape for OrderedFloat/NotNan to determine f32 vs f64
1183            let inner_is_f32 = shape
1184                .inner
1185                .map(|inner| inner.is_type::<f32>())
1186                .unwrap_or(false);
1187
1188            self.pending_opaque = Some(OpaqueScalarHint {
1189                type_identifier,
1190                inner_is_f32,
1191            });
1192            // Clear any peeked OrderedField placeholder
1193            if self
1194                .peeked
1195                .as_ref()
1196                .is_some_and(|e| matches!(e.kind, ParseEventKind::OrderedField))
1197            {
1198                self.peeked = None;
1199            }
1200        }
1201        handled
1202    }
1203}
1204
1205#[cfg(feature = "jit")]
1206impl<'de> facet_format::FormatJitParser<'de> for PostcardParser<'de> {
1207    type FormatJit = crate::jit::PostcardJitFormat;
1208
1209    fn jit_input(&self) -> &'de [u8] {
1210        self.input
1211    }
1212
1213    fn jit_pos(&self) -> Option<usize> {
1214        // Only return position if no peeked event (clean state)
1215        if self.peeked.is_some() {
1216            None
1217        } else {
1218            Some(self.pos)
1219        }
1220    }
1221
1222    fn jit_max_collection_elements(&self) -> Option<u64> {
1223        Some(self.max_collection_elements)
1224    }
1225
1226    fn jit_set_pos(&mut self, pos: usize) {
1227        self.pos = pos;
1228        self.peeked = None;
1229        // Clear state when JIT takes over
1230        self.state_stack.clear();
1231        self.pending_struct_fields = None;
1232        self.pending_scalar_type = None;
1233        self.pending_sequence = false;
1234        self.pending_array = None;
1235        self.pending_dynamic = false;
1236    }
1237
1238    fn jit_format(&self) -> Self::FormatJit {
1239        crate::jit::PostcardJitFormat
1240    }
1241
1242    fn jit_error(&self, _input: &'de [u8], error_pos: usize, error_code: i32) -> ParseError {
1243        error_from_code(error_code, error_pos)
1244    }
1245}