1use std::fmt;
4use std::io;
5
6#[derive(Debug)]
8pub enum SnappyError {
9 UnexpectedEof {
11 context: &'static str,
13 },
14 InvalidLength {
16 length: usize,
18 max_length: usize,
20 },
21 InvalidTag {
23 tag: u8,
25 offset: usize,
27 },
28 InvalidOffset {
30 offset: usize,
32 position: usize,
34 },
35 OutputLengthMismatch {
37 expected: usize,
39 actual: usize,
41 },
42 ChecksumMismatch {
44 expected: u32,
46 computed: u32,
48 },
49 InvalidChunkType {
51 chunk_type: u8,
53 },
54 InvalidStreamIdentifier,
56 CorruptedData {
58 message: String,
60 },
61 Io(io::Error),
63}
64
65impl fmt::Display for SnappyError {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 match self {
68 Self::UnexpectedEof { context } => {
69 write!(f, "unexpected end of input: {context}")
70 }
71 Self::InvalidLength { length, max_length } => {
72 write!(f, "invalid decompressed length {length} (max {max_length})")
73 }
74 Self::InvalidTag { tag, offset } => {
75 write!(f, "invalid tag byte {tag:#04x} at offset {offset}")
76 }
77 Self::InvalidOffset { offset, position } => {
78 write!(
79 f,
80 "invalid back-reference offset {offset} at output position {position}"
81 )
82 }
83 Self::OutputLengthMismatch { expected, actual } => {
84 write!(
85 f,
86 "output length mismatch: expected {expected}, got {actual}"
87 )
88 }
89 Self::ChecksumMismatch { expected, computed } => {
90 write!(
91 f,
92 "CRC32C checksum mismatch: expected {expected:#010x}, computed {computed:#010x}"
93 )
94 }
95 Self::InvalidChunkType { chunk_type } => {
96 write!(f, "invalid chunk type: {chunk_type:#04x}")
97 }
98 Self::InvalidStreamIdentifier => {
99 write!(f, "missing or invalid stream identifier")
100 }
101 Self::CorruptedData { message } => {
102 write!(f, "corrupted data: {message}")
103 }
104 Self::Io(err) => write!(f, "I/O error: {err}"),
105 }
106 }
107}
108
109impl std::error::Error for SnappyError {
110 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
111 match self {
112 Self::Io(err) => Some(err),
113 _ => None,
114 }
115 }
116}
117
118impl From<io::Error> for SnappyError {
119 fn from(err: io::Error) -> Self {
120 Self::Io(err)
121 }
122}
123
124impl From<SnappyError> for io::Error {
125 fn from(err: SnappyError) -> Self {
126 match err {
127 SnappyError::Io(e) => e,
128 other => io::Error::new(io::ErrorKind::InvalidData, other.to_string()),
129 }
130 }
131}
132
133impl From<SnappyError> for oxiarc_core::error::OxiArcError {
134 fn from(err: SnappyError) -> Self {
135 match err {
136 SnappyError::Io(e) => Self::Io(e),
137 SnappyError::ChecksumMismatch { expected, computed } => {
138 Self::CrcMismatch { expected, computed }
139 }
140 SnappyError::UnexpectedEof { .. } => Self::UnexpectedEof { expected: 0 },
141 other => Self::CorruptedData {
142 offset: 0,
143 message: other.to_string(),
144 },
145 }
146 }
147}