use std::fmt;
use std::io;
#[derive(Debug)]
pub enum SnappyError {
UnexpectedEof {
context: &'static str,
},
InvalidLength {
length: usize,
max_length: usize,
},
InvalidTag {
tag: u8,
offset: usize,
},
InvalidOffset {
offset: usize,
position: usize,
},
OutputLengthMismatch {
expected: usize,
actual: usize,
},
ChecksumMismatch {
expected: u32,
computed: u32,
},
InvalidChunkType {
chunk_type: u8,
},
InvalidStreamIdentifier,
CorruptedData {
message: String,
},
Io(io::Error),
}
impl fmt::Display for SnappyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnexpectedEof { context } => {
write!(f, "unexpected end of input: {context}")
}
Self::InvalidLength { length, max_length } => {
write!(f, "invalid decompressed length {length} (max {max_length})")
}
Self::InvalidTag { tag, offset } => {
write!(f, "invalid tag byte {tag:#04x} at offset {offset}")
}
Self::InvalidOffset { offset, position } => {
write!(
f,
"invalid back-reference offset {offset} at output position {position}"
)
}
Self::OutputLengthMismatch { expected, actual } => {
write!(
f,
"output length mismatch: expected {expected}, got {actual}"
)
}
Self::ChecksumMismatch { expected, computed } => {
write!(
f,
"CRC32C checksum mismatch: expected {expected:#010x}, computed {computed:#010x}"
)
}
Self::InvalidChunkType { chunk_type } => {
write!(f, "invalid chunk type: {chunk_type:#04x}")
}
Self::InvalidStreamIdentifier => {
write!(f, "missing or invalid stream identifier")
}
Self::CorruptedData { message } => {
write!(f, "corrupted data: {message}")
}
Self::Io(err) => write!(f, "I/O error: {err}"),
}
}
}
impl std::error::Error for SnappyError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Io(err) => Some(err),
_ => None,
}
}
}
impl From<io::Error> for SnappyError {
fn from(err: io::Error) -> Self {
Self::Io(err)
}
}
impl From<SnappyError> for io::Error {
fn from(err: SnappyError) -> Self {
match err {
SnappyError::Io(e) => e,
other => io::Error::new(io::ErrorKind::InvalidData, other.to_string()),
}
}
}
impl From<SnappyError> for oxiarc_core::error::OxiArcError {
fn from(err: SnappyError) -> Self {
match err {
SnappyError::Io(e) => Self::Io(e),
SnappyError::ChecksumMismatch { expected, computed } => {
Self::CrcMismatch { expected, computed }
}
SnappyError::UnexpectedEof { .. } => Self::UnexpectedEof { expected: 0 },
other => Self::CorruptedData {
offset: 0,
message: other.to_string(),
},
}
}
}