facet_format_postcard/
error.rs

1//! Error types for postcard Tier-2 JIT parsing.
2
3use core::fmt;
4
5/// Postcard parsing error.
6#[derive(Debug, Clone)]
7pub struct PostcardError {
8    /// Error code from JIT
9    pub code: i32,
10    /// Position in input where error occurred
11    pub pos: usize,
12    /// Human-readable message
13    pub message: String,
14}
15
16impl fmt::Display for PostcardError {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        write!(f, "{} at position {}", self.message, self.pos)
19    }
20}
21
22impl std::error::Error for PostcardError {}
23
24impl miette::Diagnostic for PostcardError {
25    fn code<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
26        Some(Box::new(format!("postcard::error::{}", self.code)))
27    }
28}
29
30/// Postcard JIT error codes.
31pub mod codes {
32    /// Unexpected end of input
33    pub const UNEXPECTED_EOF: i32 = -100;
34    /// Invalid boolean value (not 0 or 1)
35    pub const INVALID_BOOL: i32 = -101;
36    /// Varint overflow (too many continuation bytes)
37    pub const VARINT_OVERFLOW: i32 = -102;
38    /// Sequence underflow (decrement when remaining is 0)
39    pub const SEQ_UNDERFLOW: i32 = -103;
40    /// Unsupported operation (triggers fallback)
41    pub const UNSUPPORTED: i32 = -1;
42}
43
44impl PostcardError {
45    /// Create an error from a JIT error code and position.
46    pub fn from_code(code: i32, pos: usize) -> Self {
47        let message = match code {
48            codes::UNEXPECTED_EOF => "unexpected end of input".to_string(),
49            codes::INVALID_BOOL => "invalid boolean value (expected 0 or 1)".to_string(),
50            codes::VARINT_OVERFLOW => "varint overflow".to_string(),
51            codes::SEQ_UNDERFLOW => "sequence underflow (internal error)".to_string(),
52            codes::UNSUPPORTED => "unsupported operation".to_string(),
53            _ => format!("unknown error code {}", code),
54        };
55        Self { code, pos, message }
56    }
57}