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