infinite_rs/common/errors.rs
1//! Common errors used throughout `infinite-rs`.
2
3use num_enum::TryFromPrimitiveError;
4use std::io::Error as StdIoError;
5use std::num::TryFromIntError;
6use std::result::Result as StdResult;
7use std::string::FromUtf8Error;
8use thiserror::Error;
9
10use crate::{
11 module::header::ModuleVersion,
12 tag::{
13 datablock::TagSectionType,
14 structure::{TagStructLocation, TagStructType},
15 },
16};
17
18#[derive(Error, Debug)]
19/// Errors that can occur when reading a module file.
20pub enum ModuleError {
21 /// Incorrect magic number found in the module file header. Expected magic number is "ucsh" (0x64686F6D).
22 #[error("Incorrect module magic found! Expected '0x64686F6D', found {0:#X}!")]
23 IncorrectMagic(u32),
24 /// Incorrect version number found in the module file header. Expected version is 53.
25 /// While version 53 is the only fully supported version, other versions may also work.
26 #[error("Incorrect module version found!")]
27 IncorrectVersion(#[from] TryFromPrimitiveError<ModuleVersion>),
28 /// Invalid negative block index found in module file, indicating file corruption.
29 /// This error serves as a runtime assert.
30 #[error("Module file block index must be non-negative, found {0}")]
31 NegativeBlockIndex(i32),
32}
33
34#[derive(Error, Debug)]
35/// Errors that can occur when reading a tag file.
36pub enum TagError {
37 /// Incorrect magic number found in the tag file header. Expected magic number is "mohd" (0x68736375).
38 #[error("Incorrect magic found! Expected '0x68736375', found {0:#X}!")]
39 IncorrectMagic(u32),
40 /// Incorrect version number found in the tag file header. Expected version is 27.
41 /// Version 27 is used across all Infinite versions and matches Halo 5, though with different structures.
42 #[error("Incorrect version found! Expected '27', found {0}!")]
43 IncorrectVersion(i32),
44 /// File data has not been loaded. Operations require [`data_stream`](`crate::module::file::ModuleFileEntry::data_stream`) to be initialized.
45 #[error("Not been loaded yet!")]
46 NotLoaded,
47 /// Main struct designated by [`MainStruct`](`crate::tag::structure::TagStructType`) was not found in tag file.
48 #[error("Main struct not found!")]
49 MainStructNotFound,
50 /// Tag metadata headers [`tag_info`](`crate::module::file::ModuleFileEntry::tag_info`) are missing.
51 /// This occurs when attempting to read metadata from a [`RawFile`](`crate::module::file::FileEntryFlags::RAW_FILE`).
52 #[error("Does not contain tag info!")]
53 NoTagInfo,
54 /// Failed to convert integer to [`TagSectionType`].
55 /// This error should not occur as [`TagSectionType`] enum is exhaustive.
56 #[error("Invalid TagStruct type encountered!")]
57 InvalidTagSection(#[from] TryFromPrimitiveError<TagSectionType>),
58 /// Failed to convert integer to [`TagStructType`].
59 /// This error should not occur as [`TagStructType`] enum is exhaustive.
60 #[error("Invalid TagStruct type encountered!")]
61 InvalidTagStruct(#[from] TryFromPrimitiveError<TagStructType>),
62 /// Failed to convert primitive to enum in [`common_types`](`crate::tag::types::common_types`).
63 #[error("Failed to convert primitive to enum")]
64 NumEnumError,
65 /// Recursion depth reached 3 when trying to get tag path.
66 /// This should never ever happen, if it has, something has gone very wrong.
67 #[error("Recursion depth reached 3!")]
68 RecursionDepth,
69 /// Failed to convert integer to [`TagStructLocation`].
70 /// This error should not occur as [`TagStructLocation`] enum is exhaustive.
71 #[error("Invalid TagStruct location encountered!")]
72 InvalidTagStructLocation(#[from] TryFromPrimitiveError<TagStructLocation>),
73}
74
75#[derive(Error, Debug)]
76/// Errors that can occur when decompressing data.
77pub enum DecompressionError {
78 /// Buffer size is insufficient for decompressed data.
79 /// This should not occur in Infinite module decompression.
80 #[error("Buffer size overflow")]
81 BufferSizeOverflow,
82 /// Decompression failed with Kraken decompressor error code.
83 /// Negative error codes indicate decompression failure.
84 #[error("Decompression failed with error code {0}")]
85 DecompressionFailed(i32),
86}
87
88#[derive(Error, Debug)]
89/// Standard error type used throughout `infinite-rs`.
90pub enum Error {
91 /// IO error from [`std::io`] operations.
92 #[error("Failed to read from buffer!")]
93 ReadError(#[from] StdIoError),
94 /// UTF-8 decoding error in [`read_fixed_string`](`crate::common::extensions::BufReaderExt::read_fixed_string`).
95 #[error("Incorrect UTF-8 encoding found when reading string!")]
96 Utf8ReadingError(#[from] FromUtf8Error),
97 /// Kraken decompression error.
98 #[error("Error occurred while decompressing!")]
99 DecompressionError(#[from] DecompressionError),
100 /// Module file loading error.
101 #[error("Error occurred while loading a module!")]
102 ModuleError(#[from] ModuleError),
103 /// Integer type conversion error.
104 #[error("Integer conversion failed!")]
105 TryFromIntError(#[from] TryFromIntError),
106 /// Tag file loading error.
107 #[error("Error occurred while loading a tag!")]
108 TagError(#[from] TagError),
109}
110
111/// Standard result type used throughout `infinite-rs`.
112pub type Result<T> = StdResult<T, Error>;