Skip to main content

facet_xdr/
error.rs

1//! Error types for XDR parsing and serialization.
2
3use core::fmt;
4
5/// XDR parsing error.
6#[derive(Debug, Clone)]
7pub struct XdrError {
8    /// Error code
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 XdrError {
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 XdrError {}
23
24/// XDR error codes.
25pub mod codes {
26    /// Unexpected end of input
27    pub const UNEXPECTED_EOF: i32 = -100;
28    /// Invalid boolean value (not 0 or 1)
29    pub const INVALID_BOOL: i32 = -101;
30    /// Invalid optional discriminant (not 0 or 1)
31    pub const INVALID_OPTIONAL: i32 = -102;
32    /// Invalid enum discriminant
33    pub const INVALID_VARIANT: i32 = -103;
34    /// Invalid UTF-8 in string
35    pub const INVALID_UTF8: i32 = -104;
36    /// Unsupported type (e.g., i128/u128)
37    pub const UNSUPPORTED_TYPE: i32 = -105;
38    /// Position not aligned to 4 bytes
39    pub const ALIGNMENT_ERROR: i32 = -106;
40}
41
42impl XdrError {
43    /// Create an error from a code and position.
44    pub fn from_code(code: i32, pos: usize) -> Self {
45        let message = match code {
46            codes::UNEXPECTED_EOF => "unexpected end of input".to_string(),
47            codes::INVALID_BOOL => "invalid boolean value (must be 0 or 1)".to_string(),
48            codes::INVALID_OPTIONAL => "invalid optional discriminant (must be 0 or 1)".to_string(),
49            codes::INVALID_VARIANT => "invalid enum discriminant".to_string(),
50            codes::INVALID_UTF8 => "invalid UTF-8 in string".to_string(),
51            codes::UNSUPPORTED_TYPE => "unsupported type for XDR".to_string(),
52            codes::ALIGNMENT_ERROR => "position not aligned to 4 bytes".to_string(),
53            _ => format!("unknown error code {}", code),
54        };
55        Self { code, pos, message }
56    }
57
58    /// Create an error with a custom message.
59    pub fn new(code: i32, pos: usize, message: impl Into<String>) -> Self {
60        Self {
61            code,
62            pos,
63            message: message.into(),
64        }
65    }
66}
67
68/// XDR serialization error.
69#[derive(Debug)]
70pub struct XdrSerializeError {
71    /// Human-readable message
72    pub message: String,
73}
74
75impl fmt::Display for XdrSerializeError {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        f.write_str(&self.message)
78    }
79}
80
81impl std::error::Error for XdrSerializeError {}
82
83impl XdrSerializeError {
84    /// Create a new serialization error.
85    pub fn new(message: impl Into<String>) -> Self {
86        Self {
87            message: message.into(),
88        }
89    }
90}