1#![forbid(unsafe_code)]
2
3use core::fmt;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum ZstdError {
8 Compress(CompressError),
9 Decompress(DecompressError),
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum CompressError {
15 OutputTooSmall,
17 InvalidLevel(i32),
19 InvalidDictionary,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum DecompressError {
26 BadMagic,
28 BadFrameHeader,
30 BadBlockHeader,
32 BadBlockType,
34 CorruptLiterals,
36 CorruptSequences,
38 BlockTooLarge,
40 InvalidOffset,
42 FrameSizeMismatch,
44 BadFseTable,
46 BadHuffmanWeights,
48 BadHuffmanStream,
50 WindowTooLarge { requested: u64, max: u64 },
52 OutputTooSmall,
54 ChecksumMismatch { expected: u32, got: u32 },
56 DictMismatch { expected: u32, got: u32 },
58 DictRequired,
60 InvalidDictionary,
62 InputExhausted,
64 ExtraBytes,
66}
67
68impl fmt::Display for ZstdError {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 match self {
71 ZstdError::Compress(e) => write!(f, "compress: {e}"),
72 ZstdError::Decompress(e) => write!(f, "decompress: {e}"),
73 }
74 }
75}
76
77impl fmt::Display for CompressError {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 match self {
80 CompressError::OutputTooSmall => write!(f, "output buffer too small"),
81 CompressError::InvalidLevel(l) => write!(f, "invalid compression level: {l}"),
82 CompressError::InvalidDictionary => write!(f, "invalid dictionary"),
83 }
84 }
85}
86
87impl fmt::Display for DecompressError {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match self {
90 DecompressError::BadMagic => write!(f, "invalid frame magic number"),
91 DecompressError::BadFrameHeader => write!(f, "malformed frame header"),
92 DecompressError::BadBlockHeader => write!(f, "malformed block header"),
93 DecompressError::BadBlockType => write!(f, "unknown block type"),
94 DecompressError::CorruptLiterals => write!(f, "corrupt literals section"),
95 DecompressError::CorruptSequences => write!(f, "corrupt sequences section"),
96 DecompressError::BlockTooLarge => write!(f, "block size exceeds maximum"),
97 DecompressError::InvalidOffset => write!(f, "invalid match offset"),
98 DecompressError::FrameSizeMismatch => {
99 write!(f, "decoded size does not match frame content size")
100 }
101 DecompressError::BadFseTable => write!(f, "invalid FSE table description"),
102 DecompressError::BadHuffmanWeights => write!(f, "invalid Huffman weights"),
103 DecompressError::BadHuffmanStream => write!(f, "corrupt Huffman stream"),
104 DecompressError::WindowTooLarge { requested, max } => {
105 write!(f, "window size {requested} exceeds max {max}")
106 }
107 DecompressError::OutputTooSmall => write!(f, "output buffer too small"),
108 DecompressError::ChecksumMismatch { expected, got } => {
109 write!(
110 f,
111 "checksum mismatch: expected {expected:#010x}, got {got:#010x}"
112 )
113 }
114 DecompressError::DictMismatch { expected, got } => {
115 write!(f, "dictionary ID mismatch: expected {expected}, got {got}")
116 }
117 DecompressError::DictRequired => write!(f, "dictionary required but not provided"),
118 DecompressError::InvalidDictionary => write!(f, "invalid dictionary format"),
119 DecompressError::InputExhausted => write!(f, "unexpected end of input"),
120 DecompressError::ExtraBytes => write!(f, "extra bytes after frame"),
121 }
122 }
123}
124
125#[cfg(feature = "std")]
126impl std::error::Error for ZstdError {}
127#[cfg(feature = "std")]
128impl std::error::Error for CompressError {}
129#[cfg(feature = "std")]
130impl std::error::Error for DecompressError {}
131
132impl From<CompressError> for ZstdError {
133 fn from(e: CompressError) -> Self {
134 ZstdError::Compress(e)
135 }
136}
137
138impl From<DecompressError> for ZstdError {
139 fn from(e: DecompressError) -> Self {
140 ZstdError::Decompress(e)
141 }
142}