use core::fmt;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[derive(Debug)]
pub enum Error {
TooShortBuffer {
actual: usize,
expected: usize,
file: &'static str,
line: u32,
},
FileIdentifierError(String),
FileVersioningError(String),
BlockIDError {
actual: String,
expected: String,
},
#[cfg(feature = "std")]
IOError(std::io::Error),
#[cfg(not(feature = "std"))]
WriteError,
InvalidVersionString(String),
BlockLinkError(String),
BlockSerializationError(String),
ConversionChainTooDeep {
max_depth: usize,
},
ConversionChainCycle {
address: u64,
},
LinkCycle {
address: u64,
},
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::TooShortBuffer {
actual,
expected,
file,
line,
} => write!(
f,
"Buffer too small at {file}:{line}: need at least {expected} bytes, got {actual}"
),
Error::FileIdentifierError(id) => {
write!(
f,
r#"Invalid file identifier: Expected "MDF ", found {id}"#
)
}
Error::FileVersioningError(ver) => {
write!(f, r#"File version too low: Expected "> 4.1", found {ver}"#)
}
Error::BlockIDError { actual, expected } => {
write!(
f,
"Invalid block identifier: Expected {expected:?}, got {actual:?}"
)
}
#[cfg(feature = "std")]
Error::IOError(e) => write!(f, "I/O error: {e}"),
#[cfg(not(feature = "std"))]
Error::WriteError => write!(f, "Write error"),
Error::InvalidVersionString(s) => write!(f, "Invalid version string: {s}"),
Error::BlockLinkError(s) => write!(f, "Block linking error: {s}"),
Error::BlockSerializationError(s) => write!(f, "Block serialization error: {s}"),
Error::ConversionChainTooDeep { max_depth } => {
write!(
f,
"Conversion chain too deep: maximum depth of {max_depth} exceeded"
)
}
Error::ConversionChainCycle { address } => {
write!(
f,
"Conversion chain cycle detected at block address {address:#x}"
)
}
Error::LinkCycle { address } => {
write!(f, "Block link cycle detected at address {address:#x}")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::IOError(e) => Some(e),
_ => None,
}
}
}
#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Error::IOError(err)
}
}
pub type Result<T> = core::result::Result<T, Error>;