Skip to main content

kacrab_protocol/primitives/
error.rs

1//! Error types for [`crate::primitives`].
2//!
3//! Two failure modes: insufficient buffer or malformed varint. Both are
4//! deterministic from the byte stream so a position-counting context is not
5//! tracked here — callers higher up (record, frame) wrap with their own
6//! context if needed.
7
8/// Error returned by primitive read operations.
9#[derive(Debug, thiserror::Error)]
10#[error("primitive decode failed")]
11#[non_exhaustive]
12pub struct PrimitiveError {
13    /// What specifically went wrong.
14    #[source]
15    pub kind: PrimitiveErrorKind,
16}
17
18impl PrimitiveError {
19    /// Construct a `PrimitiveError` from its kind.
20    #[must_use]
21    pub const fn new(kind: PrimitiveErrorKind) -> Self {
22        Self { kind }
23    }
24}
25
26impl From<PrimitiveErrorKind> for PrimitiveError {
27    fn from(kind: PrimitiveErrorKind) -> Self {
28        Self::new(kind)
29    }
30}
31
32/// Specific reason a primitive read failed.
33#[derive(Debug, thiserror::Error)]
34#[expect(
35    variant_size_differences,
36    reason = "InsufficientData carries usize×2 context; InvalidVarint a single u8. Boxing the \
37              larger variant would slow the hot path for negligible memory savings on a \
38              short-lived error."
39)]
40#[non_exhaustive]
41pub enum PrimitiveErrorKind {
42    /// Buffer ran out before the requested width was satisfied.
43    #[error("insufficient data: needed {needed} bytes, only {available} available")]
44    InsufficientData {
45        /// Bytes the read needed.
46        needed: usize,
47        /// Bytes actually remaining in the buffer.
48        available: usize,
49    },
50
51    /// Varint exceeded the maximum allowed byte length (5 for u32, 10 for u64).
52    #[error("invalid varint: continuation bit set past byte {max_bytes}")]
53    InvalidVarint {
54        /// Maximum bytes the varint encoding allows.
55        max_bytes: u8,
56    },
57
58    /// A compact length prefix decoded to a value that overflows `i32`.
59    #[error("compact length {length} exceeds the i32 maximum")]
60    LengthOutOfRange {
61        /// The decoded length that could not fit in an `i32`.
62        length: u32,
63    },
64}