1//! Errors possible when decoding deflate/zlib/gzip
2//! streams
3
4use alloc::string::String;
5use alloc::vec;
6use alloc::vec::Vec;
7use core::fmt::{Debug, Display, Formatter};
8
9/// A struct returned when decompression fails
10///
11/// This struct contains two fields,
12///
13/// - `error`:Tells you the error that actually occured.
14/// - `data`: Gives you decoded data up until that point when
15/// the error was encountered.
16///
17/// One can recover data up to the error if they so wish but
18/// guarantees about data state is not given
19pub struct InflateDecodeErrors
20{
21 /// reason why decompression fails
22 pub error: DecodeErrorStatus,
23 /// Decoded data up until that decompression error
24 pub data: Vec<u8>
25}
26
27impl InflateDecodeErrors
28{
29 /// Create a new decode wrapper with data being
30 /// how many bytes we actually decoded before hitting an error
31 ///
32 /// # Arguments
33 /// - `error`: Error encountered during decoding
34 /// - `data`: Data up to that point of decoding
35 ///
36 /// # Returns
37 /// Itself
38 pub fn new(error: DecodeErrorStatus, data: Vec<u8>) -> InflateDecodeErrors
39 {
40 InflateDecodeErrors { error, data }
41 }
42 /// Create a new decode wrapper with an empty vector
43 ///
44 /// # Arguments
45 /// - `error`: Error encountered during decoding.
46 pub fn new_with_error(error: DecodeErrorStatus) -> InflateDecodeErrors
47 {
48 InflateDecodeErrors::new(error, data:vec![])
49 }
50}
51
52impl Debug for InflateDecodeErrors
53{
54 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result
55 {
56 writeln!(f, "{:?}", self.error)
57 }
58}
59
60pub enum DecodeErrorStatus
61{
62 /// Input data is not enough to construct
63 /// a full output
64 InsufficientData,
65 /// Anything that isn't significant
66 Generic(&'static str),
67 /// Anything that isn't significant but we need to
68 /// pass back information to the user as to what went wrong
69 GenericStr(String),
70 ///Input data was malformed.
71 CorruptData,
72 /// Limit set by the user was exceeded by
73 /// decompressed output
74 OutputLimitExceeded(usize, usize),
75 /// Output CRC does not match stored CRC.
76 ///
77 /// Only present for zlib
78 MismatchedCRC(u32, u32),
79 /// Output Adler does not match stored adler
80 ///
81 /// Only present for gzip
82 MismatchedAdler(u32, u32)
83}
84
85impl Debug for DecodeErrorStatus
86{
87 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result
88 {
89 match self
90 {
91 Self::InsufficientData => writeln!(f, "Insufficient data"),
92 Self::Generic(reason: &&str) => writeln!(f, "{reason}"),
93 Self::GenericStr(reason: &String) => writeln!(f, "{reason}"),
94 Self::CorruptData => writeln!(f, "Corrupt data"),
95 Self::OutputLimitExceeded(limit: &usize, current: &usize) => writeln!(
96 f,
97 "Output limit exceeded, set limit was {limit} and output size is {current}"
98 ),
99 Self::MismatchedCRC(expected: &u32, found: &u32) =>
100 {
101 writeln!(f, "Mismatched CRC, expected {expected} but found {found}")
102 }
103 Self::MismatchedAdler(expected: &u32, found: &u32) =>
104 {
105 writeln!(f, "Mismatched Adler, expected {expected} but found {found}")
106 }
107 }
108 }
109}
110
111impl Display for InflateDecodeErrors
112{
113 #[allow(clippy::uninlined_format_args)]
114 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result
115 {
116 writeln!(f, "{:?}", self)
117 }
118}
119
120#[cfg(feature = "std")]
121impl std::error::Error for InflateDecodeErrors {}
122