Skip to main content

hurray_io/
error.rs

1/// Crate-level error type for `hurray-io`.
2#[derive(Debug, thiserror::Error)]
3#[non_exhaustive]
4pub enum Error {
5    /// An I/O error from the underlying stream or file.
6    #[error("I/O error: {0}")]
7    Io(#[from] std::io::Error),
8
9    /// A core format error.
10    #[error("format error: {0}")]
11    Core(#[from] hurray_core::Error),
12
13    /// The stream ended before a complete record was read.
14    #[error("unexpected end of stream")]
15    UnexpectedEof,
16
17    /// A frame or record header is malformed.
18    #[error("invalid frame header: {0}")]
19    InvalidHeader(String),
20
21    /// The number of supplied buffer slices does not match the descriptor's buffer table.
22    #[error("buffer count mismatch: descriptor declares {declared}, got {actual}")]
23    MultiBufferLengthMismatch { declared: usize, actual: usize },
24
25    /// A supplied buffer's byte length does not match the corresponding handle's `byte_size`.
26    #[error("buffer[{index}] size mismatch: declared {declared}, got {actual}")]
27    BufferSizeMismatch {
28        index: usize,
29        declared: u64,
30        actual: u64,
31    },
32
33    /// A descriptor or buffer exceeded the configured size limit.
34    #[error("frame too large: {kind} = {value}, limit = {limit}")]
35    FrameTooLarge {
36        kind: &'static str,
37        value: u64,
38        limit: u64,
39    },
40
41    /// A buffer handle's `sync_mode` is invalid for a cross-machine transport.
42    #[error(
43        "buffer[{index}] sync_mode 0x{actual:02X} is invalid for cross-machine transport \
44         (must be 0x00 ProducerSynced)"
45    )]
46    InvalidCrossMachineSyncMode { index: usize, actual: u8 },
47
48    /// A composite head's members were truncated: the stream ended before the head's
49    /// declared `member_count` members had been read.
50    #[error("torn composite: head declares {declared} member(s), stream ended after {actual}")]
51    TornComposite { declared: u32, actual: u32 },
52
53    /// Composite nesting exceeded the configured maximum depth. Guards against stack
54    /// exhaustion from a maliciously deep composite on an untrusted stream.
55    #[error("composite nesting too deep: exceeded limit of {limit}")]
56    CompositeNestingTooDeep { limit: usize },
57
58    /// A composite read was requested for a tensor whose head is not a composite.
59    #[error("tensor {0:?} is not a composite head")]
60    NotAComposite(String),
61
62    // ── File format ───────────────────────────────────────────────────────────
63    /// The file header magic is not `HRRYFILE`.
64    #[error("invalid file magic: expected HRRYFILE")]
65    InvalidFileMagic,
66
67    /// The trailer magic is not `HRRY`.
68    #[error("invalid trailer magic")]
69    InvalidTrailerMagic,
70
71    /// The container major version is higher than this reader supports.
72    #[error("unsupported container version {major}.x (reader supports 1.x)")]
73    UnsupportedContainerVersion { major: u8 },
74
75    /// A tensor name was requested but is not in the file index.
76    #[error("tensor not found: {0:?}")]
77    TensorNotFound(String),
78
79    /// Two tensors in the same file share a name.
80    #[error("duplicate tensor name: {0:?}")]
81    DuplicateTensorName(String),
82
83    /// A tensor name is empty.
84    #[error("tensor name must not be empty")]
85    TensorNameEmpty,
86
87    /// A tensor name exceeds the 65 535-byte `uint16` limit.
88    #[error("tensor name too long: {len} bytes (max 65535)")]
89    TensorNameTooLong { len: usize },
90
91    /// The index CRC-32C does not match the stored value.
92    #[error("index CRC-32C mismatch: stored 0x{stored:08X}, computed 0x{computed:08X}")]
93    IndexCrc32cMismatch { stored: u32, computed: u32 },
94
95    /// Two KV entries share the same key.
96    #[error("duplicate KV key: {0:?}")]
97    DuplicateKvKey(String),
98
99    /// A KV key is empty.
100    #[error("KV key must not be empty")]
101    KvKeyEmpty,
102
103    /// A KV key exceeds the 65 535-byte `uint16` limit.
104    #[error("KV key too long: {len} bytes (max 65535)")]
105    KvKeyTooLong { len: usize },
106
107    /// A reserved flag bit was set in the file header.
108    #[error("file header has reserved flag bits set: 0x{flags:08X}")]
109    ReservedFileFlagBits { flags: u32 },
110
111    /// The index section overlaps the trailer.
112    #[error("index section overruns trailer boundary")]
113    IndexOverrunsTrailer,
114}
115
116/// Convenience alias for `Result` with [`Error`].
117pub type Result<T> = std::result::Result<T, Error>;