#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum AprFormatError {
#[error("Checksum mismatch: expected 0x{expected:08X}, got 0x{actual:08X}")]
ChecksumMismatch {
expected: u32,
actual: u32,
},
#[error("Invalid model format: {message}")]
FormatError {
message: String,
},
#[error("Serialization error: {0}")]
Serialization(String),
#[error("Validation failed: {message}")]
ValidationError {
message: String,
},
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("Invalid offset: out of bounds for the supplied buffer")]
InvalidOffset,
#[error("Header or metadata section too large")]
HeaderTooLarge,
#[error("Unsupported format version: found {}.{}, max supported {}.{}", found.0, found.1, supported.0, supported.1)]
UnsupportedVersion {
found: (u8, u8),
supported: (u8, u8),
},
}
pub type Result<T> = std::result::Result<T, AprFormatError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_checksum_mismatch_display() {
let e = AprFormatError::ChecksumMismatch {
expected: 0xDEAD_BEEF,
actual: 0xCAFE_BABE,
};
let s = e.to_string();
assert!(s.contains("Checksum mismatch"));
assert!(s.contains("DEADBEEF"));
}
#[test]
fn test_format_error_display() {
let e = AprFormatError::FormatError {
message: "corrupt header".to_string(),
};
assert!(e.to_string().contains("corrupt header"));
}
#[test]
fn test_io_from() {
let io = std::io::Error::new(std::io::ErrorKind::NotFound, "nope");
let e: AprFormatError = io.into();
assert!(matches!(e, AprFormatError::Io(_)));
}
#[test]
fn test_unsupported_version_display() {
let e = AprFormatError::UnsupportedVersion {
found: (3, 0),
supported: (1, 0),
};
assert!(e.to_string().contains("3.0"));
}
}