Skip to main content

zstd_complete/decoding/
errors.rs

1//! Errors that might occur while decoding zstd formatted data
2
3use crate::bit_io::GetBitsError;
4use crate::blocks::block::BlockType;
5use crate::blocks::literals_section::LiteralsSectionType;
6use crate::io::Error;
7use alloc::vec::Vec;
8use core::fmt;
9#[cfg(feature = "std")]
10use std::error::Error as StdError;
11
12#[derive(Debug)]
13#[non_exhaustive]
14pub enum FrameDescriptorError {
15    InvalidFrameContentSizeFlag { got: u8 },
16}
17
18impl fmt::Display for FrameDescriptorError {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        match self {
21            Self::InvalidFrameContentSizeFlag { got } => write!(
22                f,
23                "Invalid Frame_Content_Size_Flag; Is: {got}, Should be one of: 0, 1, 2, 3"
24            ),
25        }
26    }
27}
28
29#[cfg(feature = "std")]
30impl StdError for FrameDescriptorError {}
31
32#[derive(Debug)]
33#[non_exhaustive]
34pub enum FrameHeaderError {
35    WindowTooBig { got: u64 },
36    WindowTooSmall { got: u64 },
37    FrameDescriptorError(FrameDescriptorError),
38    DictIdTooSmall { got: usize, expected: usize },
39    MismatchedFrameSize { got: usize, expected: u8 },
40    FrameSizeIsZero,
41    InvalidFrameSize { got: u8 },
42}
43
44impl fmt::Display for FrameHeaderError {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match self {
47            Self::WindowTooBig { got } => write!(
48                f,
49                "window_size bigger than allowed maximum. Is: {}, Should be lower than: {}",
50                got,
51                crate::common::MAX_WINDOW_SIZE
52            ),
53            Self::WindowTooSmall { got } => write!(
54                f,
55                "window_size smaller than allowed minimum. Is: {}, Should be greater than: {}",
56                got,
57                crate::common::MIN_WINDOW_SIZE
58            ),
59            Self::FrameDescriptorError(e) => write!(f, "{e:?}"),
60            Self::DictIdTooSmall { got, expected } => write!(
61                f,
62                "Not enough bytes in dict_id. Is: {got}, Should be: {expected}"
63            ),
64            Self::MismatchedFrameSize { got, expected } => write!(
65                f,
66                "frame_content_size does not have the right length. Is: {got}, Should be: {expected}"
67            ),
68            Self::FrameSizeIsZero => write!(f, "frame_content_size was zero"),
69            Self::InvalidFrameSize { got } => write!(
70                f,
71                "Invalid frame_content_size. Is: {got}, Should be one of 1, 2, 4, 8 bytes"
72            ),
73        }
74    }
75}
76
77#[cfg(feature = "std")]
78impl StdError for FrameHeaderError {
79    fn source(&self) -> Option<&(dyn StdError + 'static)> {
80        match self {
81            FrameHeaderError::FrameDescriptorError(source) => Some(source),
82            _ => None,
83        }
84    }
85}
86
87impl From<FrameDescriptorError> for FrameHeaderError {
88    fn from(error: FrameDescriptorError) -> Self {
89        Self::FrameDescriptorError(error)
90    }
91}
92
93#[derive(Debug)]
94#[non_exhaustive]
95pub enum ReadFrameHeaderError {
96    MagicNumberReadError(Error),
97    BadMagicNumber(u32),
98    FrameDescriptorReadError(Error),
99    InvalidFrameDescriptor(FrameDescriptorError),
100    WindowDescriptorReadError(Error),
101    DictionaryIdReadError(Error),
102    FrameContentSizeReadError(Error),
103    SkipFrame { magic_number: u32, length: u32 },
104}
105
106impl fmt::Display for ReadFrameHeaderError {
107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108        match self {
109            Self::MagicNumberReadError(e) => write!(f, "Error while reading magic number: {e}"),
110            Self::BadMagicNumber(e) => write!(f, "Read wrong magic number: 0x{e:X}"),
111            Self::FrameDescriptorReadError(e) => {
112                write!(f, "Error while reading frame descriptor: {e}")
113            }
114            Self::InvalidFrameDescriptor(e) => write!(f, "{e:?}"),
115            Self::WindowDescriptorReadError(e) => {
116                write!(f, "Error while reading window descriptor: {e}")
117            }
118            Self::DictionaryIdReadError(e) => write!(f, "Error while reading dictionary id: {e}"),
119            Self::FrameContentSizeReadError(e) => {
120                write!(f, "Error while reading frame content size: {e}")
121            }
122            Self::SkipFrame {
123                magic_number,
124                length,
125            } => write!(
126                f,
127                "SkippableFrame encountered with MagicNumber 0x{magic_number:X} and length {length} bytes"
128            ),
129        }
130    }
131}
132
133#[cfg(feature = "std")]
134impl StdError for ReadFrameHeaderError {
135    fn source(&self) -> Option<&(dyn StdError + 'static)> {
136        match self {
137            ReadFrameHeaderError::MagicNumberReadError(source) => Some(source),
138            ReadFrameHeaderError::FrameDescriptorReadError(source) => Some(source),
139            ReadFrameHeaderError::InvalidFrameDescriptor(source) => Some(source),
140            ReadFrameHeaderError::WindowDescriptorReadError(source) => Some(source),
141            ReadFrameHeaderError::DictionaryIdReadError(source) => Some(source),
142            ReadFrameHeaderError::FrameContentSizeReadError(source) => Some(source),
143            _ => None,
144        }
145    }
146}
147
148impl From<FrameDescriptorError> for ReadFrameHeaderError {
149    fn from(error: FrameDescriptorError) -> Self {
150        Self::InvalidFrameDescriptor(error)
151    }
152}
153
154#[derive(Debug)]
155#[non_exhaustive]
156pub enum BlockHeaderReadError {
157    ReadError(Error),
158    FoundReservedBlock,
159    BlockTypeError(BlockTypeError),
160    BlockSizeError(BlockSizeError),
161}
162
163#[cfg(feature = "std")]
164impl std::error::Error for BlockHeaderReadError {
165    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
166        match self {
167            BlockHeaderReadError::ReadError(source) => Some(source),
168            BlockHeaderReadError::BlockTypeError(source) => Some(source),
169            BlockHeaderReadError::BlockSizeError(source) => Some(source),
170            BlockHeaderReadError::FoundReservedBlock => None,
171        }
172    }
173}
174
175impl ::core::fmt::Display for BlockHeaderReadError {
176    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
177        match self {
178            BlockHeaderReadError::ReadError(_) => write!(f, "Error while reading the block header"),
179            BlockHeaderReadError::FoundReservedBlock => write!(
180                f,
181                "Reserved block occured. This is considered corruption by the documentation"
182            ),
183            BlockHeaderReadError::BlockTypeError(e) => write!(f, "Error getting block type: {e}"),
184            BlockHeaderReadError::BlockSizeError(e) => {
185                write!(f, "Error getting block content size: {e}")
186            }
187        }
188    }
189}
190
191impl From<Error> for BlockHeaderReadError {
192    fn from(val: Error) -> Self {
193        Self::ReadError(val)
194    }
195}
196
197impl From<BlockTypeError> for BlockHeaderReadError {
198    fn from(val: BlockTypeError) -> Self {
199        Self::BlockTypeError(val)
200    }
201}
202
203impl From<BlockSizeError> for BlockHeaderReadError {
204    fn from(val: BlockSizeError) -> Self {
205        Self::BlockSizeError(val)
206    }
207}
208
209#[derive(Debug)]
210#[non_exhaustive]
211pub enum BlockTypeError {
212    InvalidBlocktypeNumber { num: u8 },
213}
214
215#[cfg(feature = "std")]
216impl std::error::Error for BlockTypeError {}
217
218impl core::fmt::Display for BlockTypeError {
219    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
220        match self {
221            BlockTypeError::InvalidBlocktypeNumber { num } => {
222                write!(f,
223                    "Invalid Blocktype number. Is: {num} Should be one of: 0, 1, 2, 3 (3 is reserved though",
224                )
225            }
226        }
227    }
228}
229
230#[derive(Debug)]
231#[non_exhaustive]
232pub enum BlockSizeError {
233    BlockSizeTooLarge { size: u32 },
234}
235
236#[cfg(feature = "std")]
237impl std::error::Error for BlockSizeError {}
238
239impl core::fmt::Display for BlockSizeError {
240    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
241        match self {
242            BlockSizeError::BlockSizeTooLarge { size } => {
243                write!(
244                    f,
245                    "Blocksize was bigger than the absolute maximum {} (128kb). Is: {}",
246                    crate::common::MAX_BLOCK_SIZE,
247                    size,
248                )
249            }
250        }
251    }
252}
253
254#[derive(Debug)]
255#[non_exhaustive]
256pub enum DecompressBlockError {
257    Capacity(crate::workspace::CapacityError),
258    BlockContentReadError(Error),
259    MalformedSectionHeader {
260        expected_len: usize,
261        remaining_bytes: usize,
262    },
263    DecompressLiteralsError(DecompressLiteralsError),
264    LiteralsSectionParseError(LiteralsSectionParseError),
265    SequencesHeaderParseError(SequencesHeaderParseError),
266    DecodeSequenceError(DecodeSequenceError),
267    ExecuteSequencesError(ExecuteSequencesError),
268}
269
270#[cfg(feature = "std")]
271impl std::error::Error for DecompressBlockError {
272    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
273        match self {
274            DecompressBlockError::BlockContentReadError(source) => Some(source),
275            DecompressBlockError::DecompressLiteralsError(source) => Some(source),
276            DecompressBlockError::LiteralsSectionParseError(source) => Some(source),
277            DecompressBlockError::SequencesHeaderParseError(source) => Some(source),
278            DecompressBlockError::DecodeSequenceError(source) => Some(source),
279            DecompressBlockError::ExecuteSequencesError(source) => Some(source),
280            _ => None,
281        }
282    }
283}
284
285impl core::fmt::Display for DecompressBlockError {
286    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
287        match self {
288            Self::Capacity(error) => write!(f, "decoder storage admission failed: {error:?}"),
289            DecompressBlockError::BlockContentReadError(e) => {
290                write!(f, "Error while reading the block content: {e}")
291            }
292            DecompressBlockError::MalformedSectionHeader {
293                expected_len,
294                remaining_bytes,
295            } => {
296                write!(f,
297                    "Malformed section header. Says literals would be this long: {expected_len} but there are only {remaining_bytes} bytes left",
298                )
299            }
300            DecompressBlockError::DecompressLiteralsError(e) => write!(f, "{e:?}"),
301            DecompressBlockError::LiteralsSectionParseError(e) => write!(f, "{e:?}"),
302            DecompressBlockError::SequencesHeaderParseError(e) => write!(f, "{e:?}"),
303            DecompressBlockError::DecodeSequenceError(e) => write!(f, "{e:?}"),
304            DecompressBlockError::ExecuteSequencesError(e) => write!(f, "{e:?}"),
305        }
306    }
307}
308
309impl From<Error> for DecompressBlockError {
310    fn from(val: Error) -> Self {
311        Self::BlockContentReadError(val)
312    }
313}
314
315impl From<DecompressLiteralsError> for DecompressBlockError {
316    fn from(val: DecompressLiteralsError) -> Self {
317        Self::DecompressLiteralsError(val)
318    }
319}
320
321impl From<LiteralsSectionParseError> for DecompressBlockError {
322    fn from(val: LiteralsSectionParseError) -> Self {
323        Self::LiteralsSectionParseError(val)
324    }
325}
326
327impl From<SequencesHeaderParseError> for DecompressBlockError {
328    fn from(val: SequencesHeaderParseError) -> Self {
329        Self::SequencesHeaderParseError(val)
330    }
331}
332
333impl From<DecodeSequenceError> for DecompressBlockError {
334    fn from(val: DecodeSequenceError) -> Self {
335        Self::DecodeSequenceError(val)
336    }
337}
338
339impl From<ExecuteSequencesError> for DecompressBlockError {
340    fn from(val: ExecuteSequencesError) -> Self {
341        Self::ExecuteSequencesError(val)
342    }
343}
344
345#[derive(Debug)]
346#[non_exhaustive]
347pub enum DecodeBlockContentError {
348    DecoderStateIsFailed,
349    ExpectedHeaderOfPreviousBlock,
350    ReadError { step: BlockType, source: Error },
351    DecompressBlockError(DecompressBlockError),
352}
353
354#[cfg(feature = "std")]
355impl std::error::Error for DecodeBlockContentError {
356    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
357        match self {
358            DecodeBlockContentError::ReadError { step: _, source } => Some(source),
359            DecodeBlockContentError::DecompressBlockError(source) => Some(source),
360            _ => None,
361        }
362    }
363}
364
365impl core::fmt::Display for DecodeBlockContentError {
366    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
367        match self {
368            DecodeBlockContentError::DecoderStateIsFailed => {
369                write!(
370                    f,
371                    "Can't decode next block if failed along the way. Results will be nonsense",
372                )
373            }
374            DecodeBlockContentError::ExpectedHeaderOfPreviousBlock => {
375                write!(f,
376                            "Can't decode next block body, while expecting to decode the header of the previous block. Results will be nonsense",
377                        )
378            }
379            DecodeBlockContentError::ReadError { step, source } => {
380                write!(f, "Error while reading bytes for {step}: {source}",)
381            }
382            DecodeBlockContentError::DecompressBlockError(e) => write!(f, "{e:?}"),
383        }
384    }
385}
386
387impl From<DecompressBlockError> for DecodeBlockContentError {
388    fn from(val: DecompressBlockError) -> Self {
389        Self::DecompressBlockError(val)
390    }
391}
392
393#[derive(Debug)]
394#[non_exhaustive]
395pub enum DecodeBufferError {
396    NotEnoughBytesInDictionary { got: usize, need: usize },
397    OffsetTooBig { offset: usize, buf_len: usize },
398}
399
400#[cfg(feature = "std")]
401impl std::error::Error for DecodeBufferError {}
402
403impl core::fmt::Display for DecodeBufferError {
404    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
405        match self {
406            DecodeBufferError::NotEnoughBytesInDictionary { got, need } => {
407                write!(
408                    f,
409                    "Need {need} bytes from the dictionary but it is only {got} bytes long",
410                )
411            }
412            DecodeBufferError::OffsetTooBig { offset, buf_len } => {
413                write!(f, "offset: {offset} bigger than buffer: {buf_len}",)
414            }
415        }
416    }
417}
418
419#[derive(Debug)]
420#[non_exhaustive]
421pub enum DictionaryDecodeError {
422    Capacity(crate::workspace::CapacityError),
423    NotEnoughBytes,
424    BadMagicNum { got: [u8; 4] },
425    FSETableError(FSETableError),
426    HuffmanTableError(HuffmanTableError),
427}
428
429#[cfg(feature = "std")]
430impl std::error::Error for DictionaryDecodeError {
431    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
432        match self {
433            DictionaryDecodeError::FSETableError(source) => Some(source),
434            DictionaryDecodeError::HuffmanTableError(source) => Some(source),
435            _ => None,
436        }
437    }
438}
439
440impl core::fmt::Display for DictionaryDecodeError {
441    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
442        match self {
443            Self::Capacity(error) => write!(f, "decoder storage admission failed: {error:?}"),
444            DictionaryDecodeError::NotEnoughBytes => write!(
445                f,
446                "The raw bytes did not contain a full valid zstd dictionary"
447            ),
448            DictionaryDecodeError::BadMagicNum { got } => {
449                write!(
450                    f,
451                    "Bad magic_num at start of the dictionary; Got: {:#04X?}, Expected: {:#04x?}",
452                    got,
453                    crate::decoding::dictionary::MAGIC_NUM,
454                )
455            }
456            DictionaryDecodeError::FSETableError(e) => write!(f, "{e:?}"),
457            DictionaryDecodeError::HuffmanTableError(e) => write!(f, "{e:?}"),
458        }
459    }
460}
461
462impl From<FSETableError> for DictionaryDecodeError {
463    fn from(val: FSETableError) -> Self {
464        Self::FSETableError(val)
465    }
466}
467
468impl From<HuffmanTableError> for DictionaryDecodeError {
469    fn from(val: HuffmanTableError) -> Self {
470        Self::HuffmanTableError(val)
471    }
472}
473
474#[derive(Debug)]
475#[non_exhaustive]
476pub enum FrameDecoderError {
477    Capacity(crate::workspace::CapacityError),
478    ReadFrameHeaderError(ReadFrameHeaderError),
479    FrameHeaderError(FrameHeaderError),
480    WindowSizeTooBig { requested: u64 },
481    DictionaryDecodeError(DictionaryDecodeError),
482    FailedToReadBlockHeader(BlockHeaderReadError),
483    FailedToReadBlockBody(DecodeBlockContentError),
484    FailedToReadChecksum(Error),
485    ChecksumMismatch,
486    NotYetInitialized,
487    FailedToInitialize(FrameHeaderError),
488    FailedToDrainDecodebuffer(Error),
489    FailedToSkipFrame,
490    TargetTooSmall,
491    DictNotProvided { dict_id: u32 },
492}
493
494#[cfg(feature = "std")]
495impl StdError for FrameDecoderError {
496    fn source(&self) -> Option<&(dyn StdError + 'static)> {
497        match self {
498            FrameDecoderError::ReadFrameHeaderError(source) => Some(source),
499            FrameDecoderError::FrameHeaderError(source) => Some(source),
500            FrameDecoderError::DictionaryDecodeError(source) => Some(source),
501            FrameDecoderError::FailedToReadBlockHeader(source) => Some(source),
502            FrameDecoderError::FailedToReadBlockBody(source) => Some(source),
503            FrameDecoderError::FailedToReadChecksum(source) => Some(source),
504            FrameDecoderError::FailedToInitialize(source) => Some(source),
505            FrameDecoderError::FailedToDrainDecodebuffer(source) => Some(source),
506            _ => None,
507        }
508    }
509}
510
511impl core::fmt::Display for FrameDecoderError {
512    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
513        match self {
514            Self::Capacity(error) => write!(f, "decoder storage admission failed: {error:?}"),
515            FrameDecoderError::ReadFrameHeaderError(e) => {
516                write!(f, "{e:?}")
517            }
518            FrameDecoderError::FrameHeaderError(e) => {
519                write!(f, "{e:?}")
520            }
521            FrameDecoderError::WindowSizeTooBig { requested } => {
522                write!(
523                    f,
524                    "Specified window_size is too big; Requested: {}, Max: {}",
525                    requested,
526                    crate::common::MAX_WINDOW_SIZE,
527                )
528            }
529            FrameDecoderError::DictionaryDecodeError(e) => {
530                write!(f, "{e:?}")
531            }
532            FrameDecoderError::FailedToReadBlockHeader(e) => {
533                write!(f, "Failed to parse/decode block body: {e}")
534            }
535            FrameDecoderError::FailedToReadBlockBody(e) => {
536                write!(f, "Failed to parse block header: {e}")
537            }
538            FrameDecoderError::FailedToReadChecksum(e) => {
539                write!(f, "Failed to read checksum: {e}")
540            }
541            FrameDecoderError::ChecksumMismatch => {
542                write!(f, "Frame checksum does not match decoded content")
543            }
544            FrameDecoderError::NotYetInitialized => {
545                write!(f, "Decoder must initialized or reset before using it",)
546            }
547            FrameDecoderError::FailedToInitialize(e) => {
548                write!(f, "Decoder encountered error while initializing: {e}")
549            }
550            FrameDecoderError::FailedToDrainDecodebuffer(e) => {
551                write!(
552                    f,
553                    "Decoder encountered error while draining the decodebuffer: {e}",
554                )
555            }
556            FrameDecoderError::FailedToSkipFrame => {
557                write!(
558                    f,
559                    "Failed to skip bytes for the length given in the frame header"
560                )
561            }
562            FrameDecoderError::TargetTooSmall => {
563                write!(f, "Target must have at least as many bytes as the contentsize of the frame reports")
564            }
565            FrameDecoderError::DictNotProvided { dict_id } => {
566                write!(f, "Frame header specified dictionary id 0x{dict_id:X} that wasnt provided by add_dict() or reset_with_dict()")
567            }
568        }
569    }
570}
571
572impl From<DictionaryDecodeError> for FrameDecoderError {
573    fn from(val: DictionaryDecodeError) -> Self {
574        Self::DictionaryDecodeError(val)
575    }
576}
577
578impl From<BlockHeaderReadError> for FrameDecoderError {
579    fn from(val: BlockHeaderReadError) -> Self {
580        Self::FailedToReadBlockHeader(val)
581    }
582}
583
584impl From<FrameHeaderError> for FrameDecoderError {
585    fn from(val: FrameHeaderError) -> Self {
586        Self::FrameHeaderError(val)
587    }
588}
589
590impl From<ReadFrameHeaderError> for FrameDecoderError {
591    fn from(val: ReadFrameHeaderError) -> Self {
592        Self::ReadFrameHeaderError(val)
593    }
594}
595
596#[derive(Debug)]
597#[non_exhaustive]
598pub enum DecompressLiteralsError {
599    Capacity(crate::workspace::CapacityError),
600    MissingCompressedSize,
601    MissingNumStreams,
602    GetBitsError(GetBitsError),
603    HuffmanTableError(HuffmanTableError),
604    HuffmanDecoderError(HuffmanDecoderError),
605    UninitializedHuffmanTable,
606    MissingBytesForJumpHeader { got: usize },
607    MissingBytesForLiterals { got: usize, needed: usize },
608    ExtraPadding { skipped_bits: i32 },
609    BitstreamReadMismatch { read_til: isize, expected: isize },
610    DecodedLiteralCountMismatch { decoded: usize, expected: usize },
611    TooManyLiterals { declared: u32 },
612}
613
614#[cfg(feature = "std")]
615impl std::error::Error for DecompressLiteralsError {
616    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
617        match self {
618            DecompressLiteralsError::GetBitsError(source) => Some(source),
619            DecompressLiteralsError::HuffmanTableError(source) => Some(source),
620            DecompressLiteralsError::HuffmanDecoderError(source) => Some(source),
621            _ => None,
622        }
623    }
624}
625impl core::fmt::Display for DecompressLiteralsError {
626    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
627        match self {
628            Self::Capacity(error) => write!(f, "decoder storage admission failed: {error:?}"),
629            DecompressLiteralsError::MissingCompressedSize => {
630                write!(f,
631                    "compressed size was none even though it must be set to something for compressed literals",
632                )
633            }
634            DecompressLiteralsError::MissingNumStreams => {
635                write!(f,
636                    "num_streams was none even though it must be set to something (1 or 4) for compressed literals",
637                )
638            }
639            DecompressLiteralsError::GetBitsError(e) => write!(f, "{e:?}"),
640            DecompressLiteralsError::HuffmanTableError(e) => write!(f, "{e:?}"),
641            DecompressLiteralsError::HuffmanDecoderError(e) => write!(f, "{e:?}"),
642            DecompressLiteralsError::UninitializedHuffmanTable => {
643                write!(
644                    f,
645                    "Tried to reuse huffman table but it was never initialized",
646                )
647            }
648            DecompressLiteralsError::MissingBytesForJumpHeader { got } => {
649                write!(f, "Need 6 bytes to decode jump header, got {got} bytes",)
650            }
651            DecompressLiteralsError::MissingBytesForLiterals { got, needed } => {
652                write!(
653                    f,
654                    "Need at least {needed} bytes to decode literals. Have: {got} bytes",
655                )
656            }
657            DecompressLiteralsError::ExtraPadding { skipped_bits } => {
658                write!(f,
659                    "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
660                )
661            }
662            DecompressLiteralsError::BitstreamReadMismatch { read_til, expected } => {
663                write!(
664                    f,
665                    "Bitstream was read till: {read_til}, should have been: {expected}",
666                )
667            }
668            DecompressLiteralsError::TooManyLiterals { declared } => {
669                write!(
670                    f,
671                    "Declared literal size {declared} exceeds the 128 KiB block limit"
672                )
673            }
674            DecompressLiteralsError::DecodedLiteralCountMismatch { decoded, expected } => {
675                write!(
676                    f,
677                    "Decoded literal count mismatch: {decoded}, expected: {expected}",
678                )
679            }
680        }
681    }
682}
683
684impl From<HuffmanDecoderError> for DecompressLiteralsError {
685    fn from(val: HuffmanDecoderError) -> Self {
686        Self::HuffmanDecoderError(val)
687    }
688}
689
690impl From<GetBitsError> for DecompressLiteralsError {
691    fn from(val: GetBitsError) -> Self {
692        Self::GetBitsError(val)
693    }
694}
695
696impl From<HuffmanTableError> for DecompressLiteralsError {
697    fn from(val: HuffmanTableError) -> Self {
698        Self::HuffmanTableError(val)
699    }
700}
701
702#[derive(Debug)]
703#[non_exhaustive]
704pub enum ExecuteSequencesError {
705    BlockOutputTooLarge,
706    DecodebufferError(DecodeBufferError),
707    NotEnoughBytesForSequence { wanted: usize, have: usize },
708    ZeroOffset,
709}
710
711impl core::fmt::Display for ExecuteSequencesError {
712    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
713        match self {
714            ExecuteSequencesError::BlockOutputTooLarge => {
715                write!(f, "Decoded sequence output exceeds the 128 KiB block limit")
716            }
717            ExecuteSequencesError::DecodebufferError(e) => {
718                write!(f, "{e:?}")
719            }
720            ExecuteSequencesError::NotEnoughBytesForSequence { wanted, have } => {
721                write!(
722                    f,
723                    "Sequence wants to copy up to byte {wanted}. Bytes in literalsbuffer: {have}"
724                )
725            }
726            ExecuteSequencesError::ZeroOffset => {
727                write!(f, "Illegal offset: 0 found")
728            }
729        }
730    }
731}
732
733#[cfg(feature = "std")]
734impl std::error::Error for ExecuteSequencesError {
735    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
736        match self {
737            ExecuteSequencesError::DecodebufferError(source) => Some(source),
738            _ => None,
739        }
740    }
741}
742
743impl From<DecodeBufferError> for ExecuteSequencesError {
744    fn from(val: DecodeBufferError) -> Self {
745        Self::DecodebufferError(val)
746    }
747}
748
749#[derive(Debug)]
750#[non_exhaustive]
751pub enum DecodeSequenceError {
752    Capacity(crate::workspace::CapacityError),
753    GetBitsError(GetBitsError),
754    FSEDecoderError(FSEDecoderError),
755    FSETableError(FSETableError),
756    ExtraPadding { skipped_bits: i32 },
757    UnsupportedOffset { offset_code: u8 },
758    ZeroOffset,
759    NotEnoughBytesForNumSequences,
760    ExtraBits { bits_remaining: isize },
761    MissingCompressionMode,
762    MissingByteForRleLlTable,
763    MissingByteForRleOfTable,
764    MissingByteForRleMlTable,
765}
766
767#[cfg(feature = "std")]
768impl std::error::Error for DecodeSequenceError {
769    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
770        match self {
771            DecodeSequenceError::GetBitsError(source) => Some(source),
772            DecodeSequenceError::FSEDecoderError(source) => Some(source),
773            DecodeSequenceError::FSETableError(source) => Some(source),
774            _ => None,
775        }
776    }
777}
778
779impl core::fmt::Display for DecodeSequenceError {
780    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
781        match self {
782            Self::Capacity(error) => write!(f, "decoder storage admission failed: {error:?}"),
783            DecodeSequenceError::GetBitsError(e) => write!(f, "{e:?}"),
784            DecodeSequenceError::FSEDecoderError(e) => write!(f, "{e:?}"),
785            DecodeSequenceError::FSETableError(e) => write!(f, "{e:?}"),
786            DecodeSequenceError::ExtraPadding { skipped_bits } => {
787                write!(f,
788                    "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
789                )
790            }
791            DecodeSequenceError::UnsupportedOffset { offset_code } => {
792                write!(
793                    f,
794                    "Do not support offsets bigger than 1<<32; got: {offset_code}",
795                )
796            }
797            DecodeSequenceError::ZeroOffset => write!(
798                f,
799                "Read an offset == 0. That is an illegal value for offsets"
800            ),
801            DecodeSequenceError::NotEnoughBytesForNumSequences => write!(
802                f,
803                "Bytestream did not contain enough bytes to decode num_sequences"
804            ),
805            DecodeSequenceError::ExtraBits { bits_remaining } => write!(f, "{bits_remaining}"),
806            DecodeSequenceError::MissingCompressionMode => write!(
807                f,
808                "compression modes are none but they must be set to something"
809            ),
810            DecodeSequenceError::MissingByteForRleLlTable => {
811                write!(f, "Need a byte to read for RLE ll table")
812            }
813            DecodeSequenceError::MissingByteForRleOfTable => {
814                write!(f, "Need a byte to read for RLE of table")
815            }
816            DecodeSequenceError::MissingByteForRleMlTable => {
817                write!(f, "Need a byte to read for RLE ml table")
818            }
819        }
820    }
821}
822
823impl From<GetBitsError> for DecodeSequenceError {
824    fn from(val: GetBitsError) -> Self {
825        Self::GetBitsError(val)
826    }
827}
828
829impl From<FSETableError> for DecodeSequenceError {
830    fn from(val: FSETableError) -> Self {
831        Self::FSETableError(val)
832    }
833}
834
835impl From<FSEDecoderError> for DecodeSequenceError {
836    fn from(val: FSEDecoderError) -> Self {
837        Self::FSEDecoderError(val)
838    }
839}
840
841#[derive(Debug)]
842#[non_exhaustive]
843pub enum LiteralsSectionParseError {
844    IllegalLiteralSectionType { got: u8 },
845    GetBitsError(GetBitsError),
846    NotEnoughBytes { have: usize, need: u8 },
847}
848
849#[cfg(feature = "std")]
850impl std::error::Error for LiteralsSectionParseError {
851    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
852        match self {
853            LiteralsSectionParseError::GetBitsError(source) => Some(source),
854            _ => None,
855        }
856    }
857}
858impl core::fmt::Display for LiteralsSectionParseError {
859    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
860        match self {
861            LiteralsSectionParseError::IllegalLiteralSectionType { got } => {
862                write!(
863                    f,
864                    "Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3"
865                )
866            }
867            LiteralsSectionParseError::GetBitsError(e) => write!(f, "{e:?}"),
868            LiteralsSectionParseError::NotEnoughBytes { have, need } => {
869                write!(
870                    f,
871                    "Not enough byte to parse the literals section header. Have: {have}, Need: {need}",
872                )
873            }
874        }
875    }
876}
877
878impl From<GetBitsError> for LiteralsSectionParseError {
879    fn from(val: GetBitsError) -> Self {
880        Self::GetBitsError(val)
881    }
882}
883
884impl core::fmt::Display for LiteralsSectionType {
885    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
886        match self {
887            LiteralsSectionType::Compressed => write!(f, "Compressed"),
888            LiteralsSectionType::Raw => write!(f, "Raw"),
889            LiteralsSectionType::RLE => write!(f, "RLE"),
890            LiteralsSectionType::Treeless => write!(f, "Treeless"),
891        }
892    }
893}
894
895#[derive(Debug)]
896#[non_exhaustive]
897pub enum SequencesHeaderParseError {
898    NotEnoughBytes { need_at_least: u8, got: usize },
899}
900
901#[cfg(feature = "std")]
902impl std::error::Error for SequencesHeaderParseError {}
903
904impl core::fmt::Display for SequencesHeaderParseError {
905    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
906        match self {
907            SequencesHeaderParseError::NotEnoughBytes { need_at_least, got } => {
908                write!(
909                    f,
910                    "source must have at least {need_at_least} bytes to parse header; got {got} bytes",
911                )
912            }
913        }
914    }
915}
916
917#[derive(Debug)]
918#[non_exhaustive]
919pub enum FSETableError {
920    Capacity(crate::workspace::CapacityError),
921    AccLogIsZero,
922    AccLogTooBig {
923        got: u8,
924        max: u8,
925    },
926    GetBitsError(GetBitsError),
927    ProbabilityCounterMismatch {
928        got: u32,
929        expected_sum: u32,
930        symbol_probabilities: Vec<i32>,
931    },
932    TooManySymbols {
933        got: usize,
934    },
935}
936
937#[cfg(feature = "std")]
938impl std::error::Error for FSETableError {
939    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
940        match self {
941            FSETableError::GetBitsError(source) => Some(source),
942            _ => None,
943        }
944    }
945}
946
947impl core::fmt::Display for FSETableError {
948    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
949        match self {
950            Self::Capacity(error) => write!(f, "table storage admission failed: {error:?}"),
951            FSETableError::AccLogIsZero => write!(f, "Acclog must be at least 1"),
952            FSETableError::AccLogTooBig { got, max } => {
953                write!(
954                    f,
955                    "Found FSE acc_log: {got} bigger than allowed maximum in this case: {max}"
956                )
957            }
958            FSETableError::GetBitsError(e) => write!(f, "{e:?}"),
959            FSETableError::ProbabilityCounterMismatch {
960                got,
961                expected_sum,
962                symbol_probabilities,
963            } => {
964                write!(f,
965                    "The counter ({got}) exceeded the expected sum: {expected_sum}. This means an error or corrupted data \n {symbol_probabilities:?}",
966                )
967            }
968            FSETableError::TooManySymbols { got } => {
969                write!(
970                    f,
971                    "There are too many symbols in this distribution: {got}. Max: 256",
972                )
973            }
974        }
975    }
976}
977
978impl From<GetBitsError> for FSETableError {
979    fn from(val: GetBitsError) -> Self {
980        Self::GetBitsError(val)
981    }
982}
983
984#[derive(Debug)]
985#[non_exhaustive]
986pub enum FSEDecoderError {
987    GetBitsError(GetBitsError),
988    TableIsUninitialized,
989}
990
991#[cfg(feature = "std")]
992impl std::error::Error for FSEDecoderError {
993    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
994        match self {
995            FSEDecoderError::GetBitsError(source) => Some(source),
996            _ => None,
997        }
998    }
999}
1000
1001impl core::fmt::Display for FSEDecoderError {
1002    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1003        match self {
1004            FSEDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1005            FSEDecoderError::TableIsUninitialized => {
1006                write!(f, "Tried to use an uninitialized table!")
1007            }
1008        }
1009    }
1010}
1011
1012impl From<GetBitsError> for FSEDecoderError {
1013    fn from(val: GetBitsError) -> Self {
1014        Self::GetBitsError(val)
1015    }
1016}
1017
1018#[derive(Debug)]
1019#[non_exhaustive]
1020pub enum HuffmanTableError {
1021    Capacity(crate::workspace::CapacityError),
1022    GetBitsError(GetBitsError),
1023    FSEDecoderError(FSEDecoderError),
1024    FSETableError(FSETableError),
1025    SourceIsEmpty,
1026    NotEnoughBytesForWeights {
1027        got_bytes: usize,
1028        expected_bytes: u8,
1029    },
1030    ExtraPadding {
1031        skipped_bits: i32,
1032    },
1033    TooManyWeights {
1034        got: usize,
1035    },
1036    MissingWeights,
1037    LeftoverIsNotAPowerOf2 {
1038        got: u32,
1039    },
1040    NotEnoughBytesToDecompressWeights {
1041        have: usize,
1042        need: usize,
1043    },
1044    FSETableUsedTooManyBytes {
1045        used: usize,
1046        available_bytes: u8,
1047    },
1048    NotEnoughBytesInSource {
1049        got: usize,
1050        need: usize,
1051    },
1052    WeightBiggerThanMaxNumBits {
1053        got: u8,
1054    },
1055    MaxBitsTooHigh {
1056        got: u8,
1057    },
1058}
1059
1060#[cfg(feature = "std")]
1061impl StdError for HuffmanTableError {
1062    fn source(&self) -> Option<&(dyn StdError + 'static)> {
1063        match self {
1064            HuffmanTableError::GetBitsError(source) => Some(source),
1065            HuffmanTableError::FSEDecoderError(source) => Some(source),
1066            HuffmanTableError::FSETableError(source) => Some(source),
1067            _ => None,
1068        }
1069    }
1070}
1071
1072impl core::fmt::Display for HuffmanTableError {
1073    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1074        match self {
1075            Self::Capacity(error) => write!(f, "table storage admission failed: {error:?}"),
1076            HuffmanTableError::GetBitsError(e) => write!(f, "{e:?}"),
1077            HuffmanTableError::FSEDecoderError(e) => write!(f, "{e:?}"),
1078            HuffmanTableError::FSETableError(e) => write!(f, "{e:?}"),
1079            HuffmanTableError::SourceIsEmpty => write!(f, "Source needs to have at least one byte"),
1080            HuffmanTableError::NotEnoughBytesForWeights {
1081                got_bytes,
1082                expected_bytes,
1083            } => {
1084                write!(f, "Header says there should be {expected_bytes} bytes for the weights but there are only {got_bytes} bytes in the stream")
1085            }
1086            HuffmanTableError::ExtraPadding { skipped_bits } => {
1087                write!(f,
1088                    "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1089                )
1090            }
1091            HuffmanTableError::TooManyWeights { got } => {
1092                write!(
1093                    f,
1094                    "More than 255 weights decoded (got {got} weights). Stream is probably corrupted",
1095                )
1096            }
1097            HuffmanTableError::MissingWeights => {
1098                write!(f, "Can\'t build huffman table without any weights")
1099            }
1100            HuffmanTableError::LeftoverIsNotAPowerOf2 { got } => {
1101                write!(f, "Leftover must be power of two but is: {got}")
1102            }
1103            HuffmanTableError::NotEnoughBytesToDecompressWeights { have, need } => {
1104                write!(
1105                    f,
1106                    "Not enough bytes in stream to decompress weights. Is: {have}, Should be: {need}",
1107                )
1108            }
1109            HuffmanTableError::FSETableUsedTooManyBytes {
1110                used,
1111                available_bytes,
1112            } => {
1113                write!(f,
1114                    "FSE table used more bytes: {used} than were meant to be used for the whole stream of huffman weights ({available_bytes})",
1115                )
1116            }
1117            HuffmanTableError::NotEnoughBytesInSource { got, need } => {
1118                write!(f, "Source needs to have at least {need} bytes, got: {got}",)
1119            }
1120            HuffmanTableError::WeightBiggerThanMaxNumBits { got } => {
1121                write!(
1122                    f,
1123                    "Cant have weight: {} bigger than max_num_bits: {}",
1124                    got,
1125                    crate::huff0::MAX_MAX_NUM_BITS,
1126                )
1127            }
1128            HuffmanTableError::MaxBitsTooHigh { got } => {
1129                write!(
1130                    f,
1131                    "max_bits derived from weights is: {} should be lower than: {}",
1132                    got,
1133                    crate::huff0::MAX_MAX_NUM_BITS,
1134                )
1135            }
1136        }
1137    }
1138}
1139
1140impl From<GetBitsError> for HuffmanTableError {
1141    fn from(val: GetBitsError) -> Self {
1142        Self::GetBitsError(val)
1143    }
1144}
1145
1146impl From<FSEDecoderError> for HuffmanTableError {
1147    fn from(val: FSEDecoderError) -> Self {
1148        Self::FSEDecoderError(val)
1149    }
1150}
1151
1152impl From<FSETableError> for HuffmanTableError {
1153    fn from(val: FSETableError) -> Self {
1154        Self::FSETableError(val)
1155    }
1156}
1157
1158#[derive(Debug)]
1159#[non_exhaustive]
1160pub enum HuffmanDecoderError {
1161    GetBitsError(GetBitsError),
1162}
1163
1164impl core::fmt::Display for HuffmanDecoderError {
1165    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1166        match self {
1167            HuffmanDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1168        }
1169    }
1170}
1171
1172#[cfg(feature = "std")]
1173impl StdError for HuffmanDecoderError {
1174    fn source(&self) -> Option<&(dyn StdError + 'static)> {
1175        match self {
1176            HuffmanDecoderError::GetBitsError(source) => Some(source),
1177        }
1178    }
1179}
1180
1181impl From<GetBitsError> for HuffmanDecoderError {
1182    fn from(val: GetBitsError) -> Self {
1183        Self::GetBitsError(val)
1184    }
1185}
1186
1187impl From<crate::workspace::CapacityError> for FSETableError {
1188    fn from(error: crate::workspace::CapacityError) -> Self { Self::Capacity(error) }
1189}
1190
1191impl From<crate::workspace::CapacityError> for HuffmanTableError {
1192    fn from(error: crate::workspace::CapacityError) -> Self { Self::Capacity(error) }
1193}
1194
1195impl From<crate::workspace::CapacityError> for DictionaryDecodeError {
1196    fn from(error: crate::workspace::CapacityError) -> Self { Self::Capacity(error) }
1197}
1198
1199impl From<crate::workspace::CapacityError> for FrameDecoderError {
1200    fn from(error: crate::workspace::CapacityError) -> Self { Self::Capacity(error) }
1201}
1202
1203impl From<crate::workspace::CapacityError> for DecompressBlockError {
1204    fn from(error: crate::workspace::CapacityError) -> Self { Self::Capacity(error) }
1205}
1206
1207impl From<crate::workspace::CapacityError> for DecompressLiteralsError {
1208    fn from(error: crate::workspace::CapacityError) -> Self { Self::Capacity(error) }
1209}
1210
1211impl From<crate::workspace::CapacityError> for DecodeSequenceError {
1212    fn from(error: crate::workspace::CapacityError) -> Self { Self::Capacity(error) }
1213}