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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
use crate::huffman::HuffmanError;
use bitreader::BitReaderError;
use std::array::TryFromSliceError;
use std::ffi::FromBytesWithNulError;
use std::fmt::Display;
use std::io::ErrorKind;
use std::str::Utf8Error;
/// Error types that may occur when reading a CHD file or hunk.
///
/// This type tries to be ABI-compatible with [libchdr](https://github.com/rtissera/libchdr/blob/6eeb6abc4adc094d489c8ba8cafdcff9ff61251b/include/libchdr/chd.h#L258),
/// given sane defaults in the C compiler. See [repr(C) in the Rustonomicon](https://doc.rust-lang.org/nomicon/other-reprs.html#reprc) for more details.
#[derive(Debug)]
#[repr(C)]
pub enum Error {
/// No error.
/// This is only used by the C API bindings.
None,
/// No drive interface.
/// This is only for C-compatibility purposes and is otherwise unused.
NoInterface,
/// Unable to allocate the required size of buffer.
OutOfMemory,
/// The file is not a valid CHD file.
InvalidFile,
/// An invalid parameter was provided.
InvalidParameter,
/// The data is invalid.
InvalidData,
/// The file was not found.
FileNotFound,
/// This CHD requires a parent CHD that was not provided.
RequiresParent,
/// The provided file is not writable.
/// Since chd-rs does not implement CHD creation, this is unused.
FileNotWriteable,
/// An error occurred when reading this CHD file.
ReadError,
/// An error occurred when writing this CHD file.
/// Since chd-rs does not implement CHD creation, this is unused.
WriteError,
/// An error occurred when initializing a codec.
CodecError,
/// The provided parent CHD is invalid.
InvalidParent,
/// The request hunk is out of range for this CHD file.
HunkOutOfRange,
/// An error occurred when decompressing a hunk.
DecompressionError,
/// An error occurred when compressing a hunk.
/// Since chd-rs does not implement CHD creation, this is unused.
CompressionError,
/// Could not create the file.
/// Since chd-rs does not implement CHD creation, this is unused.
CantCreateFile,
/// Could not verify the CHD.
/// This is only for C-compatibility purposes and is otherwise unused.
CantVerify,
/// The requested operation is not supported.
/// This is only for C-compatibility purposes and is otherwise unused.
NotSupported,
/// The requested metadata was not found.
/// This is only used by the C API bindings.
MetadataNotFound,
/// The metadata has an invalid size.
/// This is only for C-compatibility purposes and is otherwise unused.
InvalidMetadataSize,
/// The CHD version of the provided file is not supported by this library.
UnsupportedVersion,
/// Unable to verify the CHD completely.
/// This is only for C-compatibility purposes and is otherwise unused.
VerifyIncomplete,
/// The requested metadata is invalid.
InvalidMetadata,
/// The internal state of the decoder/encoder is invalid.
/// This is only for C-compatibility purposes and is otherwise unused.
InvalidState,
/// An operation is already pending.
/// This is only for C-compatibility purposes and is otherwise unused.
OperationPending,
/// No async operations are allowed.
/// This is only for C-compatibility purposes and is otherwise unused.
NoAsyncOperation,
/// Decompressing the CHD requires a codec that is not supported.
UnsupportedFormat,
/// Unknown error.
Unknown,
}
impl std::error::Error for Error {}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::None => f.write_str("no error"),
Error::NoInterface => f.write_str("no drive interface"),
Error::OutOfMemory => f.write_str("out of memory"),
Error::InvalidFile => f.write_str("invalid file"),
Error::InvalidParameter => f.write_str("invalid parameter"),
Error::InvalidData => f.write_str("invalid data"),
Error::FileNotFound => f.write_str("file not found"),
Error::RequiresParent => f.write_str("requires parent"),
Error::FileNotWriteable => f.write_str("file not writeable"),
Error::ReadError => f.write_str("read error"),
Error::WriteError => f.write_str("write error"),
Error::CodecError => f.write_str("codec error"),
Error::InvalidParent => f.write_str("invalid parent"),
Error::HunkOutOfRange => f.write_str("hunk out of range"),
Error::DecompressionError => f.write_str("decompression error"),
Error::CompressionError => f.write_str("compression error"),
Error::CantCreateFile => f.write_str("can't create file"),
Error::CantVerify => f.write_str("can't verify file"),
Error::NotSupported => f.write_str("operation not supported"),
Error::MetadataNotFound => f.write_str("can't find metadata"),
Error::InvalidMetadataSize => f.write_str("invalid metadata size"),
Error::UnsupportedVersion => f.write_str("unsupported CHD version"),
Error::VerifyIncomplete => f.write_str("incomplete verify"),
Error::InvalidMetadata => f.write_str("invalid metadata"),
Error::InvalidState => f.write_str("invalid state"),
Error::OperationPending => f.write_str("operation pending"),
Error::NoAsyncOperation => f.write_str("no async operation in progress"),
Error::UnsupportedFormat => f.write_str("unsupported format"),
Error::Unknown => f.write_str("undocumented error"),
}
}
}
impl From<TryFromSliceError> for Error {
fn from(_: TryFromSliceError) -> Self {
Error::InvalidFile
}
}
impl From<BitReaderError> for Error {
fn from(_: BitReaderError) -> Self {
Error::ReadError
}
}
impl From<FromBytesWithNulError> for Error {
fn from(_: FromBytesWithNulError) -> Self {
Error::InvalidData
}
}
impl From<Utf8Error> for Error {
fn from(_: Utf8Error) -> Self {
Error::InvalidData
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
match err.kind() {
ErrorKind::NotFound => Error::FileNotFound,
ErrorKind::PermissionDenied => Error::NotSupported,
ErrorKind::ConnectionRefused => Error::Unknown,
ErrorKind::ConnectionReset => Error::Unknown,
ErrorKind::ConnectionAborted => Error::Unknown,
ErrorKind::NotConnected => Error::Unknown,
ErrorKind::AddrInUse => Error::Unknown,
ErrorKind::AddrNotAvailable => Error::Unknown,
ErrorKind::BrokenPipe => Error::Unknown,
ErrorKind::AlreadyExists => Error::CantCreateFile,
ErrorKind::WouldBlock => Error::Unknown,
ErrorKind::InvalidInput => Error::InvalidParameter,
ErrorKind::InvalidData => Error::InvalidData,
ErrorKind::TimedOut => Error::Unknown,
ErrorKind::WriteZero => Error::WriteError,
ErrorKind::Interrupted => Error::Unknown,
ErrorKind::Other => Error::Unknown,
ErrorKind::UnexpectedEof => Error::ReadError,
ErrorKind::Unsupported => Error::NotSupported,
ErrorKind::OutOfMemory => Error::OutOfMemory,
_ => Error::Unknown,
}
}
}
impl From<HuffmanError> for Error {
fn from(_e: HuffmanError) -> Self {
Error::DecompressionError
}
}
impl From<Error> for std::io::Error {
fn from(e: Error) -> Self {
std::io::Error::new(ErrorKind::Other, e)
}
}
/// Result type for chd-rs.
pub type Result<T> = std::result::Result<T, Error>;