Skip to main content

reliakit_codec/
error.rs

1//! Error types returned by canonical encoding and decoding.
2
3use core::fmt;
4
5/// High-level category for a codec error.
6#[derive(Debug, Copy, Clone, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum CodecErrorKind {
9    /// The input ended before the requested bytes could be read.
10    UnexpectedEof,
11    /// A value used a byte or tag that is not valid for its type.
12    InvalidValue,
13    /// A decoded length cannot be represented or safely processed.
14    LengthOverflow,
15    /// A decoded value left trailing bytes in an exact decode operation.
16    TrailingBytes,
17    /// The writer failed to accept bytes.
18    WriteFailed,
19    /// The reader failed for a reason other than end of input.
20    ReadFailed,
21}
22
23/// Error returned by canonical encoding and decoding operations.
24#[derive(Debug, Copy, Clone, PartialEq, Eq)]
25pub struct CodecError {
26    kind: CodecErrorKind,
27    message: &'static str,
28}
29
30impl CodecError {
31    /// Creates a new codec error with a stable kind and actionable message.
32    pub const fn new(kind: CodecErrorKind, message: &'static str) -> Self {
33        Self { kind, message }
34    }
35
36    /// Returns the stable error category.
37    pub const fn kind(&self) -> CodecErrorKind {
38        self.kind
39    }
40
41    /// Returns a human-readable error message.
42    pub const fn message(&self) -> &'static str {
43        self.message
44    }
45
46    /// Input ended before the requested bytes could be read.
47    pub const fn unexpected_eof() -> Self {
48        Self::new(
49            CodecErrorKind::UnexpectedEof,
50            "input ended before the requested bytes could be read",
51        )
52    }
53
54    /// Value used an invalid byte or tag.
55    pub const fn invalid_value(message: &'static str) -> Self {
56        Self::new(CodecErrorKind::InvalidValue, message)
57    }
58
59    /// Decoded length cannot be represented or safely processed.
60    pub const fn length_overflow(message: &'static str) -> Self {
61        Self::new(CodecErrorKind::LengthOverflow, message)
62    }
63
64    /// Exact decode found bytes after the decoded value.
65    pub const fn trailing_bytes() -> Self {
66        Self::new(
67            CodecErrorKind::TrailingBytes,
68            "decode completed but trailing bytes remain",
69        )
70    }
71
72    /// Writer failed to accept bytes.
73    pub const fn write_failed() -> Self {
74        Self::new(CodecErrorKind::WriteFailed, "failed to write encoded bytes")
75    }
76
77    /// Reader failed for a reason other than end of input.
78    pub const fn read_failed() -> Self {
79        Self::new(CodecErrorKind::ReadFailed, "failed to read encoded bytes")
80    }
81}
82
83impl fmt::Display for CodecError {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        f.write_str(self.message)
86    }
87}
88
89#[cfg(feature = "std")]
90impl std::error::Error for CodecError {}