1use 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#[derive(Debug, Clone)]
18struct VariantMeta {
19 name: String,
20 kind: facet_core::StructKind,
21 field_count: usize,
22}
23
24#[derive(Debug, Clone)]
26enum ParserState {
27 Ready,
29 InStruct { remaining_fields: usize },
31 InSequence { remaining_elements: u64 },
33 InEnum {
35 variant_name: String,
36 variant_kind: facet_core::StructKind,
37 variant_field_count: usize,
38 field_key_emitted: bool,
39 wrapper_start_emitted: bool,
41 wrapper_end_emitted: bool,
43 },
44 InMap { remaining_entries: u64 },
47 InDynamicArray { remaining_elements: u64 },
49 InDynamicObject {
51 remaining_entries: u64,
52 expecting_key: bool,
53 },
54}
55
56pub struct PostcardParser<'de> {
61 input: &'de [u8],
62 pos: usize,
63 state_stack: Vec<ParserState>,
65 peeked: Option<ParseEvent<'de>>,
67 pending_struct_fields: Option<usize>,
69 pending_scalar_type: Option<ScalarTypeHint>,
71 pending_sequence: bool,
73 pending_byte_sequence: bool,
75 pending_array: Option<usize>,
77 pending_option: bool,
79 pending_enum: Option<Vec<VariantMeta>>,
81 pending_opaque: Option<OpaqueScalarHint>,
83 pending_map: bool,
85 pending_dynamic: bool,
87}
88
89#[derive(Debug, Clone)]
91struct OpaqueScalarHint {
92 type_identifier: &'static str,
93 inner_is_f32: bool,
95}
96
97impl<'de> PostcardParser<'de> {
98 pub const fn new(input: &'de [u8]) -> Self {
100 Self {
101 input,
102 pos: 0,
103 state_stack: Vec::new(),
104 peeked: None,
105 pending_struct_fields: None,
106 pending_scalar_type: None,
107 pending_sequence: false,
108 pending_byte_sequence: false,
109 pending_array: None,
110 pending_option: false,
111 pending_enum: None,
112 pending_opaque: None,
113 pending_map: false,
114 pending_dynamic: false,
115 }
116 }
117
118 fn read_byte(&mut self) -> Result<u8, PostcardError> {
120 if self.pos >= self.input.len() {
121 return Err(PostcardError {
122 code: codes::UNEXPECTED_EOF,
123 pos: self.pos,
124 message: "unexpected end of input".into(),
125 source_bytes: None,
126 });
127 }
128 let byte = self.input[self.pos];
129 self.pos += 1;
130 Ok(byte)
131 }
132
133 fn read_varint(&mut self) -> Result<u64, PostcardError> {
135 let mut result: u64 = 0;
136 let mut shift: u32 = 0;
137
138 loop {
139 let byte = self.read_byte()?;
140 let data = (byte & 0x7F) as u64;
141
142 if shift >= 64 {
143 return Err(PostcardError {
144 code: codes::VARINT_OVERFLOW,
145 pos: self.pos,
146 message: "varint overflow".into(),
147 source_bytes: None,
148 });
149 }
150
151 result |= data << shift;
152 shift += 7;
153
154 if (byte & 0x80) == 0 {
155 return Ok(result);
156 }
157 }
158 }
159
160 fn read_signed_varint(&mut self) -> Result<i64, PostcardError> {
162 let unsigned = self.read_varint()?;
163 let decoded = ((unsigned >> 1) as i64) ^ -((unsigned & 1) as i64);
165 Ok(decoded)
166 }
167
168 fn read_varint_u128(&mut self) -> Result<u128, PostcardError> {
170 let mut result: u128 = 0;
171 let mut shift: u32 = 0;
172
173 loop {
174 let byte = self.read_byte()?;
175 let data = (byte & 0x7F) as u128;
176
177 if shift >= 128 {
178 return Err(PostcardError {
179 code: codes::VARINT_OVERFLOW,
180 pos: self.pos,
181 message: "varint overflow for u128".into(),
182 source_bytes: None,
183 });
184 }
185
186 result |= data << shift;
187 shift += 7;
188
189 if (byte & 0x80) == 0 {
190 return Ok(result);
191 }
192 }
193 }
194
195 fn read_signed_varint_i128(&mut self) -> Result<i128, PostcardError> {
197 let unsigned = self.read_varint_u128()?;
198 let decoded = ((unsigned >> 1) as i128) ^ -((unsigned & 1) as i128);
200 Ok(decoded)
201 }
202
203 fn read_bytes(&mut self, len: usize) -> Result<&'de [u8], PostcardError> {
205 if self.pos + len > self.input.len() {
206 return Err(PostcardError {
207 code: codes::UNEXPECTED_EOF,
208 pos: self.pos,
209 message: "unexpected end of input reading bytes".into(),
210 source_bytes: None,
211 });
212 }
213 let bytes = &self.input[self.pos..self.pos + len];
214 self.pos += len;
215 Ok(bytes)
216 }
217
218 fn current_state(&self) -> &ParserState {
220 self.state_stack.last().unwrap_or(&ParserState::Ready)
221 }
222
223 fn generate_next_event(&mut self) -> Result<ParseEvent<'de>, PostcardError> {
225 if self.pending_option {
227 self.pending_option = false;
228 let discriminant = self.read_byte()?;
229 match discriminant {
230 0x00 => return Ok(ParseEvent::Scalar(ScalarValue::Null)),
231 0x01 => {
232 return Ok(ParseEvent::OrderedField);
237 }
238 _ => {
239 return Err(PostcardError {
240 code: codes::INVALID_OPTION_DISCRIMINANT,
241 pos: self.pos - 1,
242 message: format!("invalid Option discriminant: {}", discriminant),
243 source_bytes: None,
244 });
245 }
246 }
247 }
248
249 if self.pending_dynamic {
251 self.pending_dynamic = false;
252 return self.parse_dynamic_tag_event();
253 }
254
255 if let Some(variants) = self.pending_enum.take() {
257 let variant_index = self.read_varint()? as usize;
258 if variant_index >= variants.len() {
259 return Err(PostcardError {
260 code: codes::INVALID_ENUM_DISCRIMINANT,
261 pos: self.pos,
262 message: format!(
263 "enum variant index {} out of range (max {})",
264 variant_index,
265 variants.len() - 1
266 ),
267 source_bytes: None,
268 });
269 }
270 let variant = &variants[variant_index];
271 self.state_stack.push(ParserState::InEnum {
273 variant_name: variant.name.clone(),
274 variant_kind: variant.kind,
275 variant_field_count: variant.field_count,
276 field_key_emitted: false,
277 wrapper_start_emitted: false,
278 wrapper_end_emitted: false,
279 });
280 return Ok(ParseEvent::StructStart(ContainerKind::Object));
281 }
282
283 if let Some(opaque) = self.pending_opaque.take() {
285 return self.parse_opaque_scalar(opaque);
286 }
287
288 if let Some(hint) = self.pending_scalar_type.take() {
290 return self.parse_scalar_with_hint(hint);
291 }
292
293 if self.pending_sequence {
295 self.pending_sequence = false;
296 let count = self.read_varint()?;
297 self.state_stack.push(ParserState::InSequence {
298 remaining_elements: count,
299 });
300 return Ok(ParseEvent::SequenceStart(ContainerKind::Array));
301 }
302
303 if self.pending_byte_sequence {
305 self.pending_byte_sequence = false;
306 let bytes = self.parse_bytes()?;
307 return Ok(ParseEvent::Scalar(ScalarValue::Bytes(Cow::Borrowed(bytes))));
308 }
309
310 if let Some(len) = self.pending_array.take() {
312 self.state_stack.push(ParserState::InSequence {
313 remaining_elements: len as u64,
314 });
315 return Ok(ParseEvent::SequenceStart(ContainerKind::Array));
316 }
317
318 if let Some(num_fields) = self.pending_struct_fields.take() {
320 self.state_stack.push(ParserState::InStruct {
321 remaining_fields: num_fields,
322 });
323 return Ok(ParseEvent::StructStart(ContainerKind::Object));
324 }
325
326 if self.pending_map {
328 self.pending_map = false;
329 let count = self.read_varint()?;
330 self.state_stack.push(ParserState::InMap {
331 remaining_entries: count,
332 });
333 return Ok(ParseEvent::SequenceStart(ContainerKind::Array));
334 }
335
336 match self.current_state().clone() {
338 ParserState::Ready => {
339 Err(PostcardError {
341 code: codes::UNSUPPORTED,
342 pos: self.pos,
343 message: "postcard parser needs type hints (use hint_scalar_type, hint_struct_fields, or hint_sequence)".into(),
344 source_bytes: None,
345 })
346 }
347 ParserState::InStruct { remaining_fields } => {
348 if remaining_fields == 0 {
349 self.state_stack.pop();
351 Ok(ParseEvent::StructEnd)
352 } else {
353 if let Some(ParserState::InStruct { remaining_fields }) =
355 self.state_stack.last_mut()
356 {
357 *remaining_fields -= 1;
358 }
359 Ok(ParseEvent::OrderedField)
360 }
361 }
362 ParserState::InSequence { remaining_elements } => {
363 if remaining_elements == 0 {
364 self.state_stack.pop();
366 Ok(ParseEvent::SequenceEnd)
367 } else {
368 if let Some(ParserState::InSequence { remaining_elements }) =
372 self.state_stack.last_mut()
373 {
374 *remaining_elements -= 1;
375 }
376 Ok(ParseEvent::OrderedField)
377 }
378 }
379 ParserState::InEnum {
380 variant_name,
381 variant_kind,
382 variant_field_count,
383 field_key_emitted,
384 wrapper_start_emitted,
385 wrapper_end_emitted,
386 } => {
387 use facet_core::StructKind;
388
389 if !field_key_emitted {
390 if let Some(ParserState::InEnum {
392 field_key_emitted, ..
393 }) = self.state_stack.last_mut()
394 {
395 *field_key_emitted = true;
396 }
397 Ok(ParseEvent::FieldKey(FieldKey::new(
398 Cow::Owned(variant_name.clone()),
399 FieldLocationHint::KeyValue,
400 )))
401 } else if !wrapper_start_emitted {
402 match variant_kind {
404 StructKind::Unit => {
405 self.state_stack.pop();
407 Ok(ParseEvent::StructEnd)
408 }
409 StructKind::Tuple | StructKind::TupleStruct => {
410 if variant_field_count == 1 {
412 if let Some(ParserState::InEnum {
415 wrapper_start_emitted,
416 wrapper_end_emitted,
417 ..
418 }) = self.state_stack.last_mut()
419 {
420 *wrapper_start_emitted = true;
421 *wrapper_end_emitted = true; }
423 self.generate_next_event()
425 } else {
426 if let Some(ParserState::InEnum {
431 wrapper_start_emitted,
432 ..
433 }) = self.state_stack.last_mut()
434 {
435 *wrapper_start_emitted = true;
436 }
437 Ok(ParseEvent::SequenceStart(ContainerKind::Array))
438 }
439 }
440 StructKind::Struct => {
441 if let Some(ParserState::InEnum {
445 wrapper_start_emitted,
446 ..
447 }) = self.state_stack.last_mut()
448 {
449 *wrapper_start_emitted = true;
450 }
451 let field_count = if let ParserState::InEnum {
453 variant_field_count,
454 ..
455 } = self.current_state()
456 {
457 *variant_field_count
458 } else {
459 0
460 };
461 self.state_stack.push(ParserState::InStruct {
462 remaining_fields: field_count,
463 });
464 Ok(ParseEvent::StructStart(ContainerKind::Object))
465 }
466 }
467 } else if !wrapper_end_emitted {
468 match variant_kind {
470 StructKind::Unit => {
471 unreachable!()
473 }
474 StructKind::Tuple | StructKind::TupleStruct => {
475 if variant_field_count > 1 {
477 if let Some(ParserState::InEnum {
478 wrapper_end_emitted,
479 ..
480 }) = self.state_stack.last_mut()
481 {
482 *wrapper_end_emitted = true;
483 }
484 Ok(ParseEvent::SequenceEnd)
485 } else {
486 self.state_stack.pop();
488 Ok(ParseEvent::StructEnd)
489 }
490 }
491 StructKind::Struct => {
492 self.state_stack.pop();
494 Ok(ParseEvent::StructEnd)
495 }
496 }
497 } else {
498 self.state_stack.pop();
501 Ok(ParseEvent::StructEnd)
502 }
503 }
504 ParserState::InMap { remaining_entries } => {
505 if remaining_entries == 0 {
506 self.state_stack.pop();
508 Ok(ParseEvent::SequenceEnd)
509 } else {
510 if let Some(ParserState::InMap { remaining_entries }) =
514 self.state_stack.last_mut()
515 {
516 *remaining_entries -= 1;
517 }
518 Ok(ParseEvent::OrderedField)
519 }
520 }
521 ParserState::InDynamicArray { remaining_elements } => {
522 if remaining_elements == 0 {
523 self.state_stack.pop();
524 Ok(ParseEvent::SequenceEnd)
525 } else {
526 self.parse_dynamic_tag_event()
527 }
528 }
529 ParserState::InDynamicObject {
530 remaining_entries,
531 expecting_key,
532 } => {
533 if remaining_entries == 0 {
534 self.state_stack.pop();
535 Ok(ParseEvent::StructEnd)
536 } else if expecting_key {
537 let key = self.parse_string()?;
538 if let Some(ParserState::InDynamicObject { expecting_key, .. }) =
539 self.state_stack.last_mut()
540 {
541 *expecting_key = false;
542 }
543 Ok(ParseEvent::FieldKey(FieldKey::new(
544 Cow::Borrowed(key),
545 FieldLocationHint::KeyValue,
546 )))
547 } else {
548 self.parse_dynamic_tag_event()
549 }
550 }
551 }
552 }
553
554 fn parse_scalar_with_hint(
556 &mut self,
557 hint: ScalarTypeHint,
558 ) -> Result<ParseEvent<'de>, PostcardError> {
559 let scalar = match hint {
560 ScalarTypeHint::Bool => {
561 let val = self.parse_bool()?;
562 ScalarValue::Bool(val)
563 }
564 ScalarTypeHint::U8 => {
565 let val = self.parse_u8()?;
566 ScalarValue::U64(val as u64)
567 }
568 ScalarTypeHint::U16 => {
569 let val = self.parse_u16()?;
570 ScalarValue::U64(val as u64)
571 }
572 ScalarTypeHint::U32 => {
573 let val = self.parse_u32()?;
574 ScalarValue::U64(val as u64)
575 }
576 ScalarTypeHint::U64 => {
577 let val = self.parse_u64()?;
578 ScalarValue::U64(val)
579 }
580 ScalarTypeHint::U128 => {
581 let val = self.parse_u128()?;
582 ScalarValue::U128(val)
583 }
584 ScalarTypeHint::Usize => {
585 let val = self.parse_u64()?;
587 ScalarValue::U64(val)
588 }
589 ScalarTypeHint::I8 => {
590 let val = self.parse_i8()?;
591 ScalarValue::I64(val as i64)
592 }
593 ScalarTypeHint::I16 => {
594 let val = self.parse_i16()?;
595 ScalarValue::I64(val as i64)
596 }
597 ScalarTypeHint::I32 => {
598 let val = self.parse_i32()?;
599 ScalarValue::I64(val as i64)
600 }
601 ScalarTypeHint::I64 => {
602 let val = self.parse_i64()?;
603 ScalarValue::I64(val)
604 }
605 ScalarTypeHint::I128 => {
606 let val = self.parse_i128()?;
607 ScalarValue::I128(val)
608 }
609 ScalarTypeHint::Isize => {
610 let val = self.parse_i64()?;
612 ScalarValue::I64(val)
613 }
614 ScalarTypeHint::F32 => {
615 let val = self.parse_f32()?;
616 ScalarValue::F64(val as f64)
617 }
618 ScalarTypeHint::F64 => {
619 let val = self.parse_f64()?;
620 ScalarValue::F64(val)
621 }
622 ScalarTypeHint::String => {
623 let val = self.parse_string()?;
624 ScalarValue::Str(Cow::Borrowed(val))
625 }
626 ScalarTypeHint::Bytes => {
627 let val = self.parse_bytes()?;
628 ScalarValue::Bytes(Cow::Borrowed(val))
629 }
630 ScalarTypeHint::Char => {
631 let s = self.parse_string()?;
633 let mut chars = s.chars();
635 let c = chars.next().ok_or_else(|| PostcardError {
636 code: codes::INVALID_UTF8,
637 pos: self.pos,
638 message: "empty string for char".into(),
639 source_bytes: None,
640 })?;
641 if chars.next().is_some() {
642 return Err(PostcardError {
643 code: codes::INVALID_UTF8,
644 pos: self.pos,
645 message: "string contains more than one char".into(),
646 source_bytes: None,
647 });
648 }
649 ScalarValue::Str(Cow::Owned(c.to_string()))
651 }
652 };
653 Ok(ParseEvent::Scalar(scalar))
654 }
655
656 fn parse_opaque_scalar(
662 &mut self,
663 opaque: OpaqueScalarHint,
664 ) -> Result<ParseEvent<'de>, PostcardError> {
665 let scalar = match opaque.type_identifier {
666 "Uuid" | "Ulid" => {
668 let bytes = self.read_fixed_bytes(16)?;
669 ScalarValue::Bytes(Cow::Borrowed(bytes))
670 }
671 "OrderedFloat" | "NotNan" => {
674 if opaque.inner_is_f32 {
676 let val = self.parse_f32()?;
677 ScalarValue::F64(val as f64)
678 } else {
679 let val = self.parse_f64()?;
681 ScalarValue::F64(val)
682 }
683 }
684 "Utf8PathBuf" | "Utf8Path" => {
686 let val = self.parse_string()?;
687 ScalarValue::Str(Cow::Borrowed(val))
688 }
689 "DateTime<Utc>"
691 | "DateTime<Local>"
692 | "DateTime<FixedOffset>"
693 | "NaiveDateTime"
694 | "NaiveDate"
695 | "NaiveTime" => {
696 let val = self.parse_string()?;
697 ScalarValue::Str(Cow::Borrowed(val))
698 }
699 "Timestamp" | "Zoned" | "civil::DateTime" | "civil::Date" | "civil::Time" | "Span"
701 | "SignedDuration" => {
702 let val = self.parse_string()?;
703 ScalarValue::Str(Cow::Borrowed(val))
704 }
705 "UtcDateTime" | "OffsetDateTime" | "PrimitiveDateTime" | "Date" | "Time" => {
707 let val = self.parse_string()?;
708 ScalarValue::Str(Cow::Borrowed(val))
709 }
710 _ => {
712 return Err(PostcardError {
713 code: codes::UNSUPPORTED_OPAQUE_TYPE,
714 pos: self.pos,
715 message: format!("unsupported opaque type: {}", opaque.type_identifier),
716 source_bytes: None,
717 });
718 }
719 };
720 Ok(ParseEvent::Scalar(scalar))
721 }
722
723 fn read_fixed_bytes(&mut self, len: usize) -> Result<&'de [u8], PostcardError> {
725 if self.pos + len > self.input.len() {
726 return Err(PostcardError {
727 code: codes::UNEXPECTED_END_OF_INPUT,
728 pos: self.pos,
729 message: format!(
730 "expected {} bytes, only {} available",
731 len,
732 self.input.len() - self.pos
733 ),
734 source_bytes: None,
735 });
736 }
737 let bytes = &self.input[self.pos..self.pos + len];
738 self.pos += len;
739 Ok(bytes)
740 }
741
742 pub fn parse_bool(&mut self) -> Result<bool, PostcardError> {
744 let byte = self.read_byte()?;
745 match byte {
746 0 => Ok(false),
747 1 => Ok(true),
748 _ => Err(PostcardError {
749 code: codes::INVALID_BOOL,
750 pos: self.pos - 1,
751 message: "invalid boolean value".into(),
752 source_bytes: None,
753 }),
754 }
755 }
756
757 pub fn parse_u8(&mut self) -> Result<u8, PostcardError> {
759 self.read_byte()
760 }
761
762 pub fn parse_u16(&mut self) -> Result<u16, PostcardError> {
764 let val = self.read_varint()?;
765 Ok(val as u16)
766 }
767
768 pub fn parse_u32(&mut self) -> Result<u32, PostcardError> {
770 let val = self.read_varint()?;
771 Ok(val as u32)
772 }
773
774 pub fn parse_u64(&mut self) -> Result<u64, PostcardError> {
776 self.read_varint()
777 }
778
779 pub fn parse_u128(&mut self) -> Result<u128, PostcardError> {
781 self.read_varint_u128()
782 }
783
784 pub fn parse_i8(&mut self) -> Result<i8, PostcardError> {
786 let byte = self.read_byte()?;
788 Ok(byte as i8)
789 }
790
791 pub fn parse_i16(&mut self) -> Result<i16, PostcardError> {
793 let val = self.read_signed_varint()?;
794 Ok(val as i16)
795 }
796
797 pub fn parse_i32(&mut self) -> Result<i32, PostcardError> {
799 let val = self.read_signed_varint()?;
800 Ok(val as i32)
801 }
802
803 pub fn parse_i64(&mut self) -> Result<i64, PostcardError> {
805 self.read_signed_varint()
806 }
807
808 pub fn parse_i128(&mut self) -> Result<i128, PostcardError> {
810 self.read_signed_varint_i128()
811 }
812
813 pub fn parse_f32(&mut self) -> Result<f32, PostcardError> {
815 let bytes = self.read_bytes(4)?;
816 Ok(f32::from_le_bytes(bytes.try_into().unwrap()))
817 }
818
819 pub fn parse_f64(&mut self) -> Result<f64, PostcardError> {
821 let bytes = self.read_bytes(8)?;
822 Ok(f64::from_le_bytes(bytes.try_into().unwrap()))
823 }
824
825 pub fn parse_string(&mut self) -> Result<&'de str, PostcardError> {
827 let len = self.read_varint()? as usize;
828 let bytes = self.read_bytes(len)?;
829 core::str::from_utf8(bytes).map_err(|_| PostcardError {
830 code: codes::INVALID_UTF8,
831 pos: self.pos - len,
832 message: "invalid UTF-8 in string".into(),
833 source_bytes: None,
834 })
835 }
836
837 pub fn parse_bytes(&mut self) -> Result<&'de [u8], PostcardError> {
839 let len = self.read_varint()? as usize;
840 self.read_bytes(len)
841 }
842
843 pub fn begin_sequence(&mut self) -> Result<u64, PostcardError> {
845 let count = self.read_varint()?;
846 self.state_stack.push(ParserState::InSequence {
847 remaining_elements: count,
848 });
849 Ok(count)
850 }
851
852 fn parse_dynamic_tag_event(&mut self) -> Result<ParseEvent<'de>, PostcardError> {
853 if let Some(ParserState::InDynamicObject {
855 remaining_entries,
856 expecting_key,
857 }) = self.state_stack.last_mut()
858 && !*expecting_key
859 {
860 *remaining_entries = remaining_entries.saturating_sub(1);
861 *expecting_key = true;
862 }
863
864 if let Some(ParserState::InDynamicArray { remaining_elements }) =
865 self.state_stack.last_mut()
866 {
867 *remaining_elements = remaining_elements.saturating_sub(1);
868 }
869
870 let tag = self.read_byte()?;
871 match tag {
872 0 => Ok(ParseEvent::Scalar(ScalarValue::Null)),
873 1 => self.parse_scalar_with_hint(ScalarTypeHint::Bool),
874 2 => self.parse_scalar_with_hint(ScalarTypeHint::I64),
875 3 => self.parse_scalar_with_hint(ScalarTypeHint::U64),
876 4 => self.parse_scalar_with_hint(ScalarTypeHint::F64),
877 5 => self.parse_scalar_with_hint(ScalarTypeHint::String),
878 6 => self.parse_scalar_with_hint(ScalarTypeHint::Bytes),
879 7 => {
880 let count = self.read_varint()?;
881 self.state_stack.push(ParserState::InDynamicArray {
882 remaining_elements: count,
883 });
884 Ok(ParseEvent::SequenceStart(ContainerKind::Array))
885 }
886 8 => {
887 let count = self.read_varint()?;
888 self.state_stack.push(ParserState::InDynamicObject {
889 remaining_entries: count,
890 expecting_key: true,
891 });
892 Ok(ParseEvent::StructStart(ContainerKind::Object))
893 }
894 9 => self.parse_scalar_with_hint(ScalarTypeHint::String),
895 _ => Err(PostcardError {
896 code: codes::UNSUPPORTED,
897 pos: self.pos.saturating_sub(1),
898 message: format!("invalid dynamic value tag: {}", tag),
899 source_bytes: None,
900 }),
901 }
902 }
903}
904
905pub struct PostcardProbe;
909
910impl<'de> ProbeStream<'de> for PostcardProbe {
911 type Error = PostcardError;
912
913 fn next(&mut self) -> Result<Option<FieldEvidence<'de>>, Self::Error> {
914 Ok(None)
916 }
917}
918
919impl<'de> FormatParser<'de> for PostcardParser<'de> {
920 type Error = PostcardError;
921 type Probe<'a>
922 = PostcardProbe
923 where
924 Self: 'a;
925
926 fn next_event(&mut self) -> Result<Option<ParseEvent<'de>>, Self::Error> {
927 if let Some(event) = self.peeked.take() {
929 return Ok(Some(event));
930 }
931 Ok(Some(self.generate_next_event()?))
932 }
933
934 fn peek_event(&mut self) -> Result<Option<ParseEvent<'de>>, Self::Error> {
935 if self.peeked.is_none() {
936 self.peeked = Some(self.generate_next_event()?);
937 }
938 Ok(self.peeked.clone())
939 }
940
941 fn skip_value(&mut self) -> Result<(), Self::Error> {
942 Err(PostcardError {
945 code: codes::UNSUPPORTED,
946 pos: self.pos,
947 message: "skip_value not supported for postcard (non-self-describing)".into(),
948 source_bytes: None,
949 })
950 }
951
952 fn begin_probe(&mut self) -> Result<Self::Probe<'_>, Self::Error> {
953 Ok(PostcardProbe)
955 }
956
957 fn is_self_describing(&self) -> bool {
958 false
959 }
960
961 fn hint_struct_fields(&mut self, num_fields: usize) {
962 self.pending_struct_fields = Some(num_fields);
963 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
965 self.peeked = None;
966 }
967 }
968
969 fn hint_scalar_type(&mut self, hint: ScalarTypeHint) {
970 self.pending_scalar_type = Some(hint);
971 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
973 self.peeked = None;
974 }
975 }
976
977 fn hint_sequence(&mut self) {
978 self.pending_sequence = true;
979 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
981 self.peeked = None;
982 }
983 }
984
985 fn hint_byte_sequence(&mut self) -> bool {
986 self.pending_byte_sequence = true;
987 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
989 self.peeked = None;
990 }
991 true }
993
994 fn hint_array(&mut self, len: usize) {
995 self.pending_array = Some(len);
996 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
998 self.peeked = None;
999 }
1000 }
1001
1002 fn hint_option(&mut self) {
1003 self.pending_option = true;
1004 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
1006 self.peeked = None;
1007 }
1008 }
1009
1010 fn hint_enum(&mut self, variants: &[EnumVariantHint]) {
1011 let metas: Vec<VariantMeta> = variants
1013 .iter()
1014 .map(|v| VariantMeta {
1015 name: v.name.to_string(),
1016 kind: v.kind,
1017 field_count: v.field_count,
1018 })
1019 .collect();
1020 self.pending_enum = Some(metas);
1021 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
1023 self.peeked = None;
1024 }
1025 }
1026
1027 fn hint_map(&mut self) {
1028 self.pending_map = true;
1029 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
1031 self.peeked = None;
1032 }
1033 }
1034
1035 fn hint_dynamic_value(&mut self) {
1036 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
1038 self.peeked = None;
1039 }
1040 if self.peeked.is_some() {
1042 return;
1043 }
1044 self.pending_dynamic = true;
1045 }
1046
1047 fn hint_opaque_scalar(
1048 &mut self,
1049 type_identifier: &'static str,
1050 shape: &'static facet_core::Shape,
1051 ) -> bool {
1052 let handled = matches!(
1054 type_identifier,
1055 "Uuid" | "Ulid"
1057 | "OrderedFloat" | "NotNan"
1059 | "Utf8PathBuf" | "Utf8Path"
1061 | "DateTime<Utc>" | "DateTime<Local>" | "DateTime<FixedOffset>"
1063 | "NaiveDateTime" | "NaiveDate" | "NaiveTime"
1064 | "Timestamp" | "Zoned" | "civil::DateTime" | "civil::Date" | "civil::Time"
1066 | "Span" | "SignedDuration"
1067 | "UtcDateTime" | "OffsetDateTime" | "PrimitiveDateTime" | "Date" | "Time"
1069 );
1070
1071 if handled {
1072 let inner_is_f32 = shape
1074 .inner
1075 .map(|inner| inner.is_type::<f32>())
1076 .unwrap_or(false);
1077
1078 self.pending_opaque = Some(OpaqueScalarHint {
1079 type_identifier,
1080 inner_is_f32,
1081 });
1082 if matches!(self.peeked, Some(ParseEvent::OrderedField)) {
1084 self.peeked = None;
1085 }
1086 }
1087 handled
1088 }
1089}
1090
1091#[cfg(feature = "jit")]
1092impl<'de> facet_format::FormatJitParser<'de> for PostcardParser<'de> {
1093 type FormatJit = crate::jit::PostcardJitFormat;
1094
1095 fn jit_input(&self) -> &'de [u8] {
1096 self.input
1097 }
1098
1099 fn jit_pos(&self) -> Option<usize> {
1100 if self.peeked.is_some() {
1102 None
1103 } else {
1104 Some(self.pos)
1105 }
1106 }
1107
1108 fn jit_set_pos(&mut self, pos: usize) {
1109 self.pos = pos;
1110 self.peeked = None;
1111 self.state_stack.clear();
1113 self.pending_struct_fields = None;
1114 self.pending_scalar_type = None;
1115 self.pending_sequence = false;
1116 self.pending_array = None;
1117 self.pending_dynamic = false;
1118 }
1119
1120 fn jit_format(&self) -> Self::FormatJit {
1121 crate::jit::PostcardJitFormat
1122 }
1123
1124 fn jit_error(&self, _input: &'de [u8], error_pos: usize, error_code: i32) -> Self::Error {
1125 PostcardError::from_code(error_code, error_pos)
1126 }
1127}