1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::fmt;
/// Errors produced while decoding a Zstandard stream.
///
/// The taxonomy intentionally mirrors the error conditions of the C libzstd
/// (`ZSTD_ErrorCode`) so that accept/reject behavior can be compared in
/// differential tests.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
/// The input ended before a complete frame could be decoded
/// (`ZSTD_error_srcSize_wrong`).
SrcSizeWrong,
/// The first four bytes of a frame are neither the Zstandard magic
/// number nor a skippable-frame magic (`ZSTD_error_prefix_unknown`).
UnknownMagic(u32),
/// The frame header violates the specification
/// (`ZSTD_error_frameParameter_unsupported`).
FrameHeaderInvalid(&'static str),
/// The declared window size exceeds what this decoder supports
/// (`ZSTD_error_frameParameter_windowTooLarge`).
WindowTooLarge,
/// A block used the reserved block type (`ZSTD_error_corruption_detected`).
BlockTypeInvalid,
/// The compressed data is malformed (`ZSTD_error_corruption_detected`).
Corrupted(&'static str),
/// The frame's XXH64 content checksum did not match
/// (`ZSTD_error_checksum_wrong`).
ChecksumMismatch { expected: u32, actual: u32 },
/// The frame was compressed with a dictionary, but none was supplied to
/// the decoder (`ZSTD_error_dictionary_wrong`). The payload is the
/// dictionary ID the frame asks for.
DictionaryRequired(u32),
/// A dictionary was supplied, but its ID does not match the one the frame
/// requires (`ZSTD_error_dictionary_wrong`).
DictionaryWrong { expected: u32, actual: u32 },
/// A supplied dictionary buffer began with the `ZDICT` magic but could not
/// be parsed (`ZSTD_error_dictionary_corrupted`).
DictionaryCorrupted,
/// The frame declared a content size that does not match the number of
/// bytes actually regenerated (`ZSTD_error_corruption_detected`).
FrameContentSizeMismatch,
/// Decoding would exceed the output limit given to
/// [`decompress_with_limit`](crate::decompress_with_limit).
OutputTooLarge,
/// An internal invariant was violated while encoding — e.g. a table log
/// out of range, or a distribution that does not normalize
/// (`ZSTD_error_GENERIC` on the compression path). Reserved for the
/// in-progress compressor.
Encode(&'static str),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::SrcSizeWrong => write!(f, "input is truncated or has trailing garbage"),
Error::UnknownMagic(m) => write!(f, "unknown frame magic number {m:#010x}"),
Error::FrameHeaderInvalid(why) => write!(f, "invalid frame header: {why}"),
Error::WindowTooLarge => write!(f, "frame window size is too large"),
Error::BlockTypeInvalid => write!(f, "reserved block type"),
Error::Corrupted(why) => write!(f, "corrupted compressed data: {why}"),
Error::ChecksumMismatch { expected, actual } => write!(
f,
"content checksum mismatch: stored {expected:#010x}, computed {actual:#010x}"
),
Error::DictionaryRequired(id) => {
write!(f, "frame requires dictionary {id}, but none was supplied")
}
Error::DictionaryWrong { expected, actual } => write!(
f,
"wrong dictionary: frame requires ID {expected}, supplied dictionary has ID {actual}"
),
Error::DictionaryCorrupted => write!(f, "supplied dictionary is malformed"),
Error::FrameContentSizeMismatch => {
write!(
f,
"regenerated size does not match the declared frame content size"
)
}
Error::OutputTooLarge => write!(f, "decompressed output exceeds the configured limit"),
Error::Encode(why) => write!(f, "encoding error: {why}"),
}
}
}
impl std::error::Error for Error {}