Skip to main content

rustyhdf5_format/
error.rs

1//! Error types for HDF5 format parsing.
2
3#[cfg(not(feature = "std"))]
4extern crate alloc;
5
6#[cfg(not(feature = "std"))]
7use alloc::string::String;
8
9#[cfg(feature = "std")]
10use std::string::String;
11
12use core::fmt;
13
14/// Errors that can occur when parsing HDF5 binary format structures.
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum FormatError {
17    /// The HDF5 magic signature was not found at any valid offset.
18    SignatureNotFound,
19    /// The superblock version is not supported.
20    UnsupportedVersion(u8),
21    /// Unexpected end of data.
22    UnexpectedEof {
23        /// Number of bytes expected.
24        expected: usize,
25        /// Number of bytes actually available.
26        available: usize,
27    },
28    /// Invalid offset size (must be 2, 4, or 8).
29    InvalidOffsetSize(u8),
30    /// Invalid length size (must be 2, 4, or 8).
31    InvalidLengthSize(u8),
32    /// Invalid object header signature.
33    InvalidObjectHeaderSignature,
34    /// Invalid object header version.
35    InvalidObjectHeaderVersion(u8),
36    /// Unknown message type that is marked as must-understand.
37    UnsupportedMessage(u16),
38    /// Invalid datatype class.
39    InvalidDatatypeClass(u8),
40    /// Invalid datatype version for a given class.
41    InvalidDatatypeVersion {
42        /// The type class.
43        class: u8,
44        /// The version found.
45        version: u8,
46    },
47    /// Invalid string padding type.
48    InvalidStringPadding(u8),
49    /// Invalid character set.
50    InvalidCharacterSet(u8),
51    /// Invalid byte order.
52    InvalidByteOrder(u8),
53    /// Invalid reference type.
54    InvalidReferenceType(u8),
55    /// Invalid dataspace version.
56    InvalidDataspaceVersion(u8),
57    /// Invalid dataspace type.
58    InvalidDataspaceType(u8),
59    /// Invalid data layout version.
60    InvalidLayoutVersion(u8),
61    /// Invalid data layout class.
62    InvalidLayoutClass(u8),
63    /// No data allocated for contiguous layout.
64    NoDataAllocated,
65    /// Type mismatch when reading data.
66    TypeMismatch {
67        /// Expected type description.
68        expected: &'static str,
69        /// Actual type description.
70        actual: &'static str,
71    },
72    /// Data size mismatch.
73    DataSizeMismatch {
74        /// Expected size in bytes.
75        expected: usize,
76        /// Actual size in bytes.
77        actual: usize,
78    },
79    /// Invalid local heap signature.
80    InvalidLocalHeapSignature,
81    /// Invalid local heap version.
82    InvalidLocalHeapVersion(u8),
83    /// Invalid B-tree v1 signature.
84    InvalidBTreeSignature,
85    /// Invalid B-tree node type.
86    InvalidBTreeNodeType(u8),
87    /// Invalid symbol table node signature.
88    InvalidSymbolTableNodeSignature,
89    /// Invalid symbol table node version.
90    InvalidSymbolTableNodeVersion(u8),
91    /// Path not found during group traversal.
92    PathNotFound(String),
93    /// Invalid Link message version.
94    InvalidLinkVersion(u8),
95    /// Invalid link type code.
96    InvalidLinkType(u8),
97    /// Invalid Link Info message version.
98    InvalidLinkInfoVersion(u8),
99    /// Invalid Group Info message version.
100    InvalidGroupInfoVersion(u8),
101    /// Invalid B-tree v2 signature.
102    InvalidBTreeV2Signature,
103    /// Invalid B-tree v2 version.
104    InvalidBTreeV2Version(u8),
105    /// Invalid fractal heap signature.
106    InvalidFractalHeapSignature,
107    /// Invalid fractal heap version.
108    InvalidFractalHeapVersion(u8),
109    /// Invalid heap ID type.
110    InvalidHeapIdType(u8),
111    /// Invalid attribute message version.
112    InvalidAttributeVersion(u8),
113    /// Invalid Attribute Info message version.
114    InvalidAttributeInfoVersion(u8),
115    /// Invalid shared message version.
116    InvalidSharedMessageVersion(u8),
117    /// Invalid SOHM table version.
118    InvalidSohmTableVersion(u8),
119    /// Invalid SOHM table signature (expected "SMTB").
120    InvalidSohmTableSignature,
121    /// Invalid SOHM list signature (expected "SMLI").
122    InvalidSohmListSignature,
123    /// Invalid global heap collection signature.
124    InvalidGlobalHeapSignature,
125    /// Invalid global heap version.
126    InvalidGlobalHeapVersion(u8),
127    /// Global heap object not found.
128    GlobalHeapObjectNotFound {
129        /// Address of the collection.
130        collection_address: u64,
131        /// Index that was not found.
132        index: u16,
133    },
134    /// Variable-length data error.
135    VlDataError(String),
136    /// Serialization error.
137    SerializationError(String),
138    /// Dataset is missing data.
139    DatasetMissingData,
140    /// Dataset is missing shape.
141    DatasetMissingShape,
142    /// Invalid filter pipeline version.
143    InvalidFilterPipelineVersion(u8),
144    /// Unsupported filter ID.
145    UnsupportedFilter(u16),
146    /// Filter processing error.
147    FilterError(String),
148    /// Decompression error.
149    DecompressionError(String),
150    /// Compression error.
151    CompressionError(String),
152    /// Fletcher32 checksum mismatch.
153    Fletcher32Mismatch {
154        /// Expected checksum.
155        expected: u32,
156        /// Computed checksum.
157        computed: u32,
158    },
159    /// Chunked dataset read error.
160    ChunkedReadError(String),
161    /// Chunk assembly error.
162    ChunkAssemblyError(String),
163    /// CRC32C checksum mismatch.
164    ChecksumMismatch {
165        /// The checksum stored in the file.
166        expected: u32,
167        /// The checksum we computed.
168        computed: u32,
169    },
170    /// Maximum nesting/continuation depth exceeded (malformed data protection).
171    NestingDepthExceeded,
172    /// Duplicate dataset name detected during parallel metadata merge.
173    DuplicateDatasetName(String),
174}
175
176impl fmt::Display for FormatError {
177    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178        match self {
179            FormatError::SignatureNotFound => {
180                write!(f, "HDF5 signature not found at any valid offset")
181            }
182            FormatError::UnsupportedVersion(v) => {
183                write!(f, "unsupported superblock version: {v}")
184            }
185            FormatError::UnexpectedEof {
186                expected,
187                available,
188            } => {
189                write!(f, "unexpected EOF: need {expected} bytes, have {available}")
190            }
191            FormatError::InvalidOffsetSize(s) => {
192                write!(f, "invalid offset size: {s} (must be 2, 4, or 8)")
193            }
194            FormatError::InvalidLengthSize(s) => {
195                write!(f, "invalid length size: {s} (must be 2, 4, or 8)")
196            }
197            FormatError::InvalidObjectHeaderSignature => {
198                write!(f, "invalid object header signature")
199            }
200            FormatError::InvalidObjectHeaderVersion(v) => {
201                write!(f, "invalid object header version: {v}")
202            }
203            FormatError::UnsupportedMessage(id) => {
204                write!(
205                    f,
206                    "unsupported message type {id:#06x} marked as must-understand"
207                )
208            }
209            FormatError::InvalidDatatypeClass(c) => {
210                write!(f, "invalid datatype class: {c}")
211            }
212            FormatError::InvalidDatatypeVersion { class, version } => {
213                write!(
214                    f,
215                    "invalid datatype version {version} for class {class}"
216                )
217            }
218            FormatError::InvalidStringPadding(p) => {
219                write!(f, "invalid string padding type: {p}")
220            }
221            FormatError::InvalidCharacterSet(c) => {
222                write!(f, "invalid character set: {c}")
223            }
224            FormatError::InvalidByteOrder(b) => {
225                write!(f, "invalid byte order: {b}")
226            }
227            FormatError::InvalidReferenceType(r) => {
228                write!(f, "invalid reference type: {r}")
229            }
230            FormatError::InvalidDataspaceVersion(v) => {
231                write!(f, "invalid dataspace version: {v}")
232            }
233            FormatError::InvalidDataspaceType(t) => {
234                write!(f, "invalid dataspace type: {t}")
235            }
236            FormatError::InvalidLayoutVersion(v) => {
237                write!(f, "invalid data layout version: {v}")
238            }
239            FormatError::InvalidLayoutClass(c) => {
240                write!(f, "invalid data layout class: {c}")
241            }
242            FormatError::NoDataAllocated => {
243                write!(f, "no data allocated for contiguous layout")
244            }
245            FormatError::TypeMismatch { expected, actual } => {
246                write!(f, "type mismatch: expected {expected}, got {actual}")
247            }
248            FormatError::DataSizeMismatch { expected, actual } => {
249                write!(
250                    f,
251                    "data size mismatch: expected {expected} bytes, got {actual} bytes"
252                )
253            }
254            FormatError::InvalidLocalHeapSignature => {
255                write!(f, "invalid local heap signature")
256            }
257            FormatError::InvalidLocalHeapVersion(v) => {
258                write!(f, "invalid local heap version: {v}")
259            }
260            FormatError::InvalidBTreeSignature => {
261                write!(f, "invalid B-tree v1 signature")
262            }
263            FormatError::InvalidBTreeNodeType(t) => {
264                write!(f, "invalid B-tree node type: {t}")
265            }
266            FormatError::InvalidSymbolTableNodeSignature => {
267                write!(f, "invalid symbol table node signature")
268            }
269            FormatError::InvalidSymbolTableNodeVersion(v) => {
270                write!(f, "invalid symbol table node version: {v}")
271            }
272            FormatError::PathNotFound(p) => {
273                write!(f, "path not found: {p}")
274            }
275            FormatError::InvalidLinkVersion(v) => {
276                write!(f, "invalid link message version: {v}")
277            }
278            FormatError::InvalidLinkType(t) => {
279                write!(f, "invalid link type: {t}")
280            }
281            FormatError::InvalidLinkInfoVersion(v) => {
282                write!(f, "invalid link info message version: {v}")
283            }
284            FormatError::InvalidGroupInfoVersion(v) => {
285                write!(f, "invalid group info message version: {v}")
286            }
287            FormatError::InvalidBTreeV2Signature => {
288                write!(f, "invalid B-tree v2 signature")
289            }
290            FormatError::InvalidBTreeV2Version(v) => {
291                write!(f, "invalid B-tree v2 version: {v}")
292            }
293            FormatError::InvalidFractalHeapSignature => {
294                write!(f, "invalid fractal heap signature")
295            }
296            FormatError::InvalidFractalHeapVersion(v) => {
297                write!(f, "invalid fractal heap version: {v}")
298            }
299            FormatError::InvalidHeapIdType(t) => {
300                write!(f, "invalid heap ID type: {t}")
301            }
302            FormatError::InvalidAttributeVersion(v) => {
303                write!(f, "invalid attribute message version: {v}")
304            }
305            FormatError::InvalidAttributeInfoVersion(v) => {
306                write!(f, "invalid attribute info message version: {v}")
307            }
308            FormatError::InvalidSharedMessageVersion(v) => {
309                write!(f, "invalid shared message version: {v}")
310            }
311            FormatError::InvalidSohmTableVersion(v) => {
312                write!(f, "invalid SOHM table version: {v}")
313            }
314            FormatError::InvalidSohmTableSignature => {
315                write!(f, "invalid SOHM table signature (expected SMTB)")
316            }
317            FormatError::InvalidSohmListSignature => {
318                write!(f, "invalid SOHM list signature (expected SMLI)")
319            }
320            FormatError::InvalidGlobalHeapSignature => {
321                write!(f, "invalid global heap collection signature")
322            }
323            FormatError::InvalidGlobalHeapVersion(v) => {
324                write!(f, "invalid global heap version: {v}")
325            }
326            FormatError::GlobalHeapObjectNotFound { collection_address, index } => {
327                write!(f, "global heap object not found: collection {collection_address:#x}, index {index}")
328            }
329            FormatError::VlDataError(msg) => {
330                write!(f, "variable-length data error: {msg}")
331            }
332            FormatError::SerializationError(msg) => {
333                write!(f, "serialization error: {msg}")
334            }
335            FormatError::DatasetMissingData => {
336                write!(f, "dataset is missing data")
337            }
338            FormatError::DatasetMissingShape => {
339                write!(f, "dataset is missing shape")
340            }
341            FormatError::InvalidFilterPipelineVersion(v) => {
342                write!(f, "invalid filter pipeline version: {v}")
343            }
344            FormatError::UnsupportedFilter(id) => {
345                write!(f, "unsupported filter: {id}")
346            }
347            FormatError::FilterError(msg) => {
348                write!(f, "filter error: {msg}")
349            }
350            FormatError::DecompressionError(msg) => {
351                write!(f, "decompression error: {msg}")
352            }
353            FormatError::CompressionError(msg) => {
354                write!(f, "compression error: {msg}")
355            }
356            FormatError::Fletcher32Mismatch { expected, computed } => {
357                write!(
358                    f,
359                    "fletcher32 mismatch: expected {expected:#010x}, computed {computed:#010x}"
360                )
361            }
362            FormatError::ChunkedReadError(msg) => {
363                write!(f, "chunked read error: {msg}")
364            }
365            FormatError::ChunkAssemblyError(msg) => {
366                write!(f, "chunk assembly error: {msg}")
367            }
368            FormatError::ChecksumMismatch { expected, computed } => {
369                write!(
370                    f,
371                    "checksum mismatch: expected {expected:#010x}, computed {computed:#010x}"
372                )
373            }
374            FormatError::NestingDepthExceeded => {
375                write!(f, "maximum nesting/continuation depth exceeded")
376            }
377            FormatError::DuplicateDatasetName(name) => {
378                write!(f, "duplicate dataset name during parallel merge: {name}")
379            }
380        }
381    }
382}
383
384#[cfg(feature = "std")]
385impl std::error::Error for FormatError {}