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