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