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    BlockContentReadError(Error),
258    MalformedSectionHeader {
259        expected_len: usize,
260        remaining_bytes: usize,
261    },
262    DecompressLiteralsError(DecompressLiteralsError),
263    LiteralsSectionParseError(LiteralsSectionParseError),
264    SequencesHeaderParseError(SequencesHeaderParseError),
265    DecodeSequenceError(DecodeSequenceError),
266    ExecuteSequencesError(ExecuteSequencesError),
267}
268
269#[cfg(feature = "std")]
270impl std::error::Error for DecompressBlockError {
271    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
272        match self {
273            DecompressBlockError::BlockContentReadError(source) => Some(source),
274            DecompressBlockError::DecompressLiteralsError(source) => Some(source),
275            DecompressBlockError::LiteralsSectionParseError(source) => Some(source),
276            DecompressBlockError::SequencesHeaderParseError(source) => Some(source),
277            DecompressBlockError::DecodeSequenceError(source) => Some(source),
278            DecompressBlockError::ExecuteSequencesError(source) => Some(source),
279            _ => None,
280        }
281    }
282}
283
284impl core::fmt::Display for DecompressBlockError {
285    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
286        match self {
287            DecompressBlockError::BlockContentReadError(e) => {
288                write!(f, "Error while reading the block content: {e}")
289            }
290            DecompressBlockError::MalformedSectionHeader {
291                expected_len,
292                remaining_bytes,
293            } => {
294                write!(f,
295                    "Malformed section header. Says literals would be this long: {expected_len} but there are only {remaining_bytes} bytes left",
296                )
297            }
298            DecompressBlockError::DecompressLiteralsError(e) => write!(f, "{e:?}"),
299            DecompressBlockError::LiteralsSectionParseError(e) => write!(f, "{e:?}"),
300            DecompressBlockError::SequencesHeaderParseError(e) => write!(f, "{e:?}"),
301            DecompressBlockError::DecodeSequenceError(e) => write!(f, "{e:?}"),
302            DecompressBlockError::ExecuteSequencesError(e) => write!(f, "{e:?}"),
303        }
304    }
305}
306
307impl From<Error> for DecompressBlockError {
308    fn from(val: Error) -> Self {
309        Self::BlockContentReadError(val)
310    }
311}
312
313impl From<DecompressLiteralsError> for DecompressBlockError {
314    fn from(val: DecompressLiteralsError) -> Self {
315        Self::DecompressLiteralsError(val)
316    }
317}
318
319impl From<LiteralsSectionParseError> for DecompressBlockError {
320    fn from(val: LiteralsSectionParseError) -> Self {
321        Self::LiteralsSectionParseError(val)
322    }
323}
324
325impl From<SequencesHeaderParseError> for DecompressBlockError {
326    fn from(val: SequencesHeaderParseError) -> Self {
327        Self::SequencesHeaderParseError(val)
328    }
329}
330
331impl From<DecodeSequenceError> for DecompressBlockError {
332    fn from(val: DecodeSequenceError) -> Self {
333        Self::DecodeSequenceError(val)
334    }
335}
336
337impl From<ExecuteSequencesError> for DecompressBlockError {
338    fn from(val: ExecuteSequencesError) -> Self {
339        Self::ExecuteSequencesError(val)
340    }
341}
342
343#[derive(Debug)]
344#[non_exhaustive]
345pub enum DecodeBlockContentError {
346    DecoderStateIsFailed,
347    ExpectedHeaderOfPreviousBlock,
348    ReadError { step: BlockType, source: Error },
349    DecompressBlockError(DecompressBlockError),
350}
351
352#[cfg(feature = "std")]
353impl std::error::Error for DecodeBlockContentError {
354    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
355        match self {
356            DecodeBlockContentError::ReadError { step: _, source } => Some(source),
357            DecodeBlockContentError::DecompressBlockError(source) => Some(source),
358            _ => None,
359        }
360    }
361}
362
363impl core::fmt::Display for DecodeBlockContentError {
364    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
365        match self {
366            DecodeBlockContentError::DecoderStateIsFailed => {
367                write!(
368                    f,
369                    "Can't decode next block if failed along the way. Results will be nonsense",
370                )
371            }
372            DecodeBlockContentError::ExpectedHeaderOfPreviousBlock => {
373                write!(f,
374                            "Can't decode next block body, while expecting to decode the header of the previous block. Results will be nonsense",
375                        )
376            }
377            DecodeBlockContentError::ReadError { step, source } => {
378                write!(f, "Error while reading bytes for {step}: {source}",)
379            }
380            DecodeBlockContentError::DecompressBlockError(e) => write!(f, "{e:?}"),
381        }
382    }
383}
384
385impl From<DecompressBlockError> for DecodeBlockContentError {
386    fn from(val: DecompressBlockError) -> Self {
387        Self::DecompressBlockError(val)
388    }
389}
390
391#[derive(Debug)]
392#[non_exhaustive]
393pub enum DecodeBufferError {
394    NotEnoughBytesInDictionary { got: usize, need: usize },
395    OffsetTooBig { offset: usize, buf_len: usize },
396}
397
398#[cfg(feature = "std")]
399impl std::error::Error for DecodeBufferError {}
400
401impl core::fmt::Display for DecodeBufferError {
402    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
403        match self {
404            DecodeBufferError::NotEnoughBytesInDictionary { got, need } => {
405                write!(
406                    f,
407                    "Need {need} bytes from the dictionary but it is only {got} bytes long",
408                )
409            }
410            DecodeBufferError::OffsetTooBig { offset, buf_len } => {
411                write!(f, "offset: {offset} bigger than buffer: {buf_len}",)
412            }
413        }
414    }
415}
416
417#[derive(Debug)]
418#[non_exhaustive]
419pub enum DictionaryDecodeError {
420    NotEnoughBytes,
421    BadMagicNum { got: [u8; 4] },
422    FSETableError(FSETableError),
423    HuffmanTableError(HuffmanTableError),
424}
425
426#[cfg(feature = "std")]
427impl std::error::Error for DictionaryDecodeError {
428    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
429        match self {
430            DictionaryDecodeError::FSETableError(source) => Some(source),
431            DictionaryDecodeError::HuffmanTableError(source) => Some(source),
432            _ => None,
433        }
434    }
435}
436
437impl core::fmt::Display for DictionaryDecodeError {
438    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
439        match self {
440            DictionaryDecodeError::NotEnoughBytes => write!(
441                f,
442                "The raw bytes did not contain a full valid zstd dictionary"
443            ),
444            DictionaryDecodeError::BadMagicNum { got } => {
445                write!(
446                    f,
447                    "Bad magic_num at start of the dictionary; Got: {:#04X?}, Expected: {:#04x?}",
448                    got,
449                    crate::decoding::dictionary::MAGIC_NUM,
450                )
451            }
452            DictionaryDecodeError::FSETableError(e) => write!(f, "{e:?}"),
453            DictionaryDecodeError::HuffmanTableError(e) => write!(f, "{e:?}"),
454        }
455    }
456}
457
458impl From<FSETableError> for DictionaryDecodeError {
459    fn from(val: FSETableError) -> Self {
460        Self::FSETableError(val)
461    }
462}
463
464impl From<HuffmanTableError> for DictionaryDecodeError {
465    fn from(val: HuffmanTableError) -> Self {
466        Self::HuffmanTableError(val)
467    }
468}
469
470#[derive(Debug)]
471#[non_exhaustive]
472pub enum FrameDecoderError {
473    ReadFrameHeaderError(ReadFrameHeaderError),
474    FrameHeaderError(FrameHeaderError),
475    WindowSizeTooBig { requested: u64 },
476    DictionaryDecodeError(DictionaryDecodeError),
477    FailedToReadBlockHeader(BlockHeaderReadError),
478    FailedToReadBlockBody(DecodeBlockContentError),
479    FailedToReadChecksum(Error),
480    NotYetInitialized,
481    FailedToInitialize(FrameHeaderError),
482    FailedToDrainDecodebuffer(Error),
483    FailedToSkipFrame,
484    TargetTooSmall,
485    DictNotProvided { dict_id: u32 },
486}
487
488#[cfg(feature = "std")]
489impl StdError for FrameDecoderError {
490    fn source(&self) -> Option<&(dyn StdError + 'static)> {
491        match self {
492            FrameDecoderError::ReadFrameHeaderError(source) => Some(source),
493            FrameDecoderError::FrameHeaderError(source) => Some(source),
494            FrameDecoderError::DictionaryDecodeError(source) => Some(source),
495            FrameDecoderError::FailedToReadBlockHeader(source) => Some(source),
496            FrameDecoderError::FailedToReadBlockBody(source) => Some(source),
497            FrameDecoderError::FailedToReadChecksum(source) => Some(source),
498            FrameDecoderError::FailedToInitialize(source) => Some(source),
499            FrameDecoderError::FailedToDrainDecodebuffer(source) => Some(source),
500            _ => None,
501        }
502    }
503}
504
505impl core::fmt::Display for FrameDecoderError {
506    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
507        match self {
508            FrameDecoderError::ReadFrameHeaderError(e) => {
509                write!(f, "{e:?}")
510            }
511            FrameDecoderError::FrameHeaderError(e) => {
512                write!(f, "{e:?}")
513            }
514            FrameDecoderError::WindowSizeTooBig { requested } => {
515                write!(
516                    f,
517                    "Specified window_size is too big; Requested: {}, Max: {}",
518                    requested,
519                    crate::common::MAX_WINDOW_SIZE,
520                )
521            }
522            FrameDecoderError::DictionaryDecodeError(e) => {
523                write!(f, "{e:?}")
524            }
525            FrameDecoderError::FailedToReadBlockHeader(e) => {
526                write!(f, "Failed to parse/decode block body: {e}")
527            }
528            FrameDecoderError::FailedToReadBlockBody(e) => {
529                write!(f, "Failed to parse block header: {e}")
530            }
531            FrameDecoderError::FailedToReadChecksum(e) => {
532                write!(f, "Failed to read checksum: {e}")
533            }
534            FrameDecoderError::NotYetInitialized => {
535                write!(f, "Decoder must initialized or reset before using it",)
536            }
537            FrameDecoderError::FailedToInitialize(e) => {
538                write!(f, "Decoder encountered error while initializing: {e}")
539            }
540            FrameDecoderError::FailedToDrainDecodebuffer(e) => {
541                write!(
542                    f,
543                    "Decoder encountered error while draining the decodebuffer: {e}",
544                )
545            }
546            FrameDecoderError::FailedToSkipFrame => {
547                write!(
548                    f,
549                    "Failed to skip bytes for the length given in the frame header"
550                )
551            }
552            FrameDecoderError::TargetTooSmall => {
553                write!(f, "Target must have at least as many bytes as the contentsize of the frame reports")
554            }
555            FrameDecoderError::DictNotProvided { dict_id } => {
556                write!(f, "Frame header specified dictionary id 0x{dict_id:X} that wasnt provided by add_dict() or reset_with_dict()")
557            }
558        }
559    }
560}
561
562impl From<DictionaryDecodeError> for FrameDecoderError {
563    fn from(val: DictionaryDecodeError) -> Self {
564        Self::DictionaryDecodeError(val)
565    }
566}
567
568impl From<BlockHeaderReadError> for FrameDecoderError {
569    fn from(val: BlockHeaderReadError) -> Self {
570        Self::FailedToReadBlockHeader(val)
571    }
572}
573
574impl From<FrameHeaderError> for FrameDecoderError {
575    fn from(val: FrameHeaderError) -> Self {
576        Self::FrameHeaderError(val)
577    }
578}
579
580impl From<ReadFrameHeaderError> for FrameDecoderError {
581    fn from(val: ReadFrameHeaderError) -> Self {
582        Self::ReadFrameHeaderError(val)
583    }
584}
585
586#[derive(Debug)]
587#[non_exhaustive]
588pub enum DecompressLiteralsError {
589    MissingCompressedSize,
590    MissingNumStreams,
591    GetBitsError(GetBitsError),
592    HuffmanTableError(HuffmanTableError),
593    HuffmanDecoderError(HuffmanDecoderError),
594    UninitializedHuffmanTable,
595    MissingBytesForJumpHeader { got: usize },
596    MissingBytesForLiterals { got: usize, needed: usize },
597    ExtraPadding { skipped_bits: i32 },
598    BitstreamReadMismatch { read_til: isize, expected: isize },
599    DecodedLiteralCountMismatch { decoded: usize, expected: usize },
600}
601
602#[cfg(feature = "std")]
603impl std::error::Error for DecompressLiteralsError {
604    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
605        match self {
606            DecompressLiteralsError::GetBitsError(source) => Some(source),
607            DecompressLiteralsError::HuffmanTableError(source) => Some(source),
608            DecompressLiteralsError::HuffmanDecoderError(source) => Some(source),
609            _ => None,
610        }
611    }
612}
613impl core::fmt::Display for DecompressLiteralsError {
614    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
615        match self {
616            DecompressLiteralsError::MissingCompressedSize => {
617                write!(f,
618                    "compressed size was none even though it must be set to something for compressed literals",
619                )
620            }
621            DecompressLiteralsError::MissingNumStreams => {
622                write!(f,
623                    "num_streams was none even though it must be set to something (1 or 4) for compressed literals",
624                )
625            }
626            DecompressLiteralsError::GetBitsError(e) => write!(f, "{e:?}"),
627            DecompressLiteralsError::HuffmanTableError(e) => write!(f, "{e:?}"),
628            DecompressLiteralsError::HuffmanDecoderError(e) => write!(f, "{e:?}"),
629            DecompressLiteralsError::UninitializedHuffmanTable => {
630                write!(
631                    f,
632                    "Tried to reuse huffman table but it was never initialized",
633                )
634            }
635            DecompressLiteralsError::MissingBytesForJumpHeader { got } => {
636                write!(f, "Need 6 bytes to decode jump header, got {got} bytes",)
637            }
638            DecompressLiteralsError::MissingBytesForLiterals { got, needed } => {
639                write!(
640                    f,
641                    "Need at least {needed} bytes to decode literals. Have: {got} bytes",
642                )
643            }
644            DecompressLiteralsError::ExtraPadding { skipped_bits } => {
645                write!(f,
646                    "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
647                )
648            }
649            DecompressLiteralsError::BitstreamReadMismatch { read_til, expected } => {
650                write!(
651                    f,
652                    "Bitstream was read till: {read_til}, should have been: {expected}",
653                )
654            }
655            DecompressLiteralsError::DecodedLiteralCountMismatch { decoded, expected } => {
656                write!(
657                    f,
658                    "Did not decode enough literals: {decoded}, Should have been: {expected}",
659                )
660            }
661        }
662    }
663}
664
665impl From<HuffmanDecoderError> for DecompressLiteralsError {
666    fn from(val: HuffmanDecoderError) -> Self {
667        Self::HuffmanDecoderError(val)
668    }
669}
670
671impl From<GetBitsError> for DecompressLiteralsError {
672    fn from(val: GetBitsError) -> Self {
673        Self::GetBitsError(val)
674    }
675}
676
677impl From<HuffmanTableError> for DecompressLiteralsError {
678    fn from(val: HuffmanTableError) -> Self {
679        Self::HuffmanTableError(val)
680    }
681}
682
683#[derive(Debug)]
684#[non_exhaustive]
685pub enum ExecuteSequencesError {
686    DecodebufferError(DecodeBufferError),
687    NotEnoughBytesForSequence { wanted: usize, have: usize },
688    ZeroOffset,
689}
690
691impl core::fmt::Display for ExecuteSequencesError {
692    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
693        match self {
694            ExecuteSequencesError::DecodebufferError(e) => {
695                write!(f, "{e:?}")
696            }
697            ExecuteSequencesError::NotEnoughBytesForSequence { wanted, have } => {
698                write!(
699                    f,
700                    "Sequence wants to copy up to byte {wanted}. Bytes in literalsbuffer: {have}"
701                )
702            }
703            ExecuteSequencesError::ZeroOffset => {
704                write!(f, "Illegal offset: 0 found")
705            }
706        }
707    }
708}
709
710#[cfg(feature = "std")]
711impl std::error::Error for ExecuteSequencesError {
712    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
713        match self {
714            ExecuteSequencesError::DecodebufferError(source) => Some(source),
715            _ => None,
716        }
717    }
718}
719
720impl From<DecodeBufferError> for ExecuteSequencesError {
721    fn from(val: DecodeBufferError) -> Self {
722        Self::DecodebufferError(val)
723    }
724}
725
726#[derive(Debug)]
727#[non_exhaustive]
728pub enum DecodeSequenceError {
729    GetBitsError(GetBitsError),
730    FSEDecoderError(FSEDecoderError),
731    FSETableError(FSETableError),
732    ExtraPadding { skipped_bits: i32 },
733    UnsupportedOffset { offset_code: u8 },
734    ZeroOffset,
735    NotEnoughBytesForNumSequences,
736    ExtraBits { bits_remaining: isize },
737    MissingCompressionMode,
738    MissingByteForRleLlTable,
739    MissingByteForRleOfTable,
740    MissingByteForRleMlTable,
741}
742
743#[cfg(feature = "std")]
744impl std::error::Error for DecodeSequenceError {
745    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
746        match self {
747            DecodeSequenceError::GetBitsError(source) => Some(source),
748            DecodeSequenceError::FSEDecoderError(source) => Some(source),
749            DecodeSequenceError::FSETableError(source) => Some(source),
750            _ => None,
751        }
752    }
753}
754
755impl core::fmt::Display for DecodeSequenceError {
756    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
757        match self {
758            DecodeSequenceError::GetBitsError(e) => write!(f, "{e:?}"),
759            DecodeSequenceError::FSEDecoderError(e) => write!(f, "{e:?}"),
760            DecodeSequenceError::FSETableError(e) => write!(f, "{e:?}"),
761            DecodeSequenceError::ExtraPadding { skipped_bits } => {
762                write!(f,
763                    "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
764                )
765            }
766            DecodeSequenceError::UnsupportedOffset { offset_code } => {
767                write!(
768                    f,
769                    "Do not support offsets bigger than 1<<32; got: {offset_code}",
770                )
771            }
772            DecodeSequenceError::ZeroOffset => write!(
773                f,
774                "Read an offset == 0. That is an illegal value for offsets"
775            ),
776            DecodeSequenceError::NotEnoughBytesForNumSequences => write!(
777                f,
778                "Bytestream did not contain enough bytes to decode num_sequences"
779            ),
780            DecodeSequenceError::ExtraBits { bits_remaining } => write!(f, "{bits_remaining}"),
781            DecodeSequenceError::MissingCompressionMode => write!(
782                f,
783                "compression modes are none but they must be set to something"
784            ),
785            DecodeSequenceError::MissingByteForRleLlTable => {
786                write!(f, "Need a byte to read for RLE ll table")
787            }
788            DecodeSequenceError::MissingByteForRleOfTable => {
789                write!(f, "Need a byte to read for RLE of table")
790            }
791            DecodeSequenceError::MissingByteForRleMlTable => {
792                write!(f, "Need a byte to read for RLE ml table")
793            }
794        }
795    }
796}
797
798impl From<GetBitsError> for DecodeSequenceError {
799    fn from(val: GetBitsError) -> Self {
800        Self::GetBitsError(val)
801    }
802}
803
804impl From<FSETableError> for DecodeSequenceError {
805    fn from(val: FSETableError) -> Self {
806        Self::FSETableError(val)
807    }
808}
809
810impl From<FSEDecoderError> for DecodeSequenceError {
811    fn from(val: FSEDecoderError) -> Self {
812        Self::FSEDecoderError(val)
813    }
814}
815
816#[derive(Debug)]
817#[non_exhaustive]
818pub enum LiteralsSectionParseError {
819    IllegalLiteralSectionType { got: u8 },
820    GetBitsError(GetBitsError),
821    NotEnoughBytes { have: usize, need: u8 },
822}
823
824#[cfg(feature = "std")]
825impl std::error::Error for LiteralsSectionParseError {
826    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
827        match self {
828            LiteralsSectionParseError::GetBitsError(source) => Some(source),
829            _ => None,
830        }
831    }
832}
833impl core::fmt::Display for LiteralsSectionParseError {
834    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
835        match self {
836            LiteralsSectionParseError::IllegalLiteralSectionType { got } => {
837                write!(
838                    f,
839                    "Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3"
840                )
841            }
842            LiteralsSectionParseError::GetBitsError(e) => write!(f, "{e:?}"),
843            LiteralsSectionParseError::NotEnoughBytes { have, need } => {
844                write!(
845                    f,
846                    "Not enough byte to parse the literals section header. Have: {have}, Need: {need}",
847                )
848            }
849        }
850    }
851}
852
853impl From<GetBitsError> for LiteralsSectionParseError {
854    fn from(val: GetBitsError) -> Self {
855        Self::GetBitsError(val)
856    }
857}
858
859impl core::fmt::Display for LiteralsSectionType {
860    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
861        match self {
862            LiteralsSectionType::Compressed => write!(f, "Compressed"),
863            LiteralsSectionType::Raw => write!(f, "Raw"),
864            LiteralsSectionType::RLE => write!(f, "RLE"),
865            LiteralsSectionType::Treeless => write!(f, "Treeless"),
866        }
867    }
868}
869
870#[derive(Debug)]
871#[non_exhaustive]
872pub enum SequencesHeaderParseError {
873    NotEnoughBytes { need_at_least: u8, got: usize },
874}
875
876#[cfg(feature = "std")]
877impl std::error::Error for SequencesHeaderParseError {}
878
879impl core::fmt::Display for SequencesHeaderParseError {
880    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
881        match self {
882            SequencesHeaderParseError::NotEnoughBytes { need_at_least, got } => {
883                write!(
884                    f,
885                    "source must have at least {need_at_least} bytes to parse header; got {got} bytes",
886                )
887            }
888        }
889    }
890}
891
892#[derive(Debug)]
893#[non_exhaustive]
894pub enum FSETableError {
895    AccLogIsZero,
896    AccLogTooBig {
897        got: u8,
898        max: u8,
899    },
900    GetBitsError(GetBitsError),
901    ProbabilityCounterMismatch {
902        got: u32,
903        expected_sum: u32,
904        symbol_probabilities: Vec<i32>,
905    },
906    TooManySymbols {
907        got: usize,
908    },
909}
910
911#[cfg(feature = "std")]
912impl std::error::Error for FSETableError {
913    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
914        match self {
915            FSETableError::GetBitsError(source) => Some(source),
916            _ => None,
917        }
918    }
919}
920
921impl core::fmt::Display for FSETableError {
922    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
923        match self {
924            FSETableError::AccLogIsZero => write!(f, "Acclog must be at least 1"),
925            FSETableError::AccLogTooBig { got, max } => {
926                write!(
927                    f,
928                    "Found FSE acc_log: {got} bigger than allowed maximum in this case: {max}"
929                )
930            }
931            FSETableError::GetBitsError(e) => write!(f, "{e:?}"),
932            FSETableError::ProbabilityCounterMismatch {
933                got,
934                expected_sum,
935                symbol_probabilities,
936            } => {
937                write!(f,
938                    "The counter ({got}) exceeded the expected sum: {expected_sum}. This means an error or corrupted data \n {symbol_probabilities:?}",
939                )
940            }
941            FSETableError::TooManySymbols { got } => {
942                write!(
943                    f,
944                    "There are too many symbols in this distribution: {got}. Max: 256",
945                )
946            }
947        }
948    }
949}
950
951impl From<GetBitsError> for FSETableError {
952    fn from(val: GetBitsError) -> Self {
953        Self::GetBitsError(val)
954    }
955}
956
957#[derive(Debug)]
958#[non_exhaustive]
959pub enum FSEDecoderError {
960    GetBitsError(GetBitsError),
961    TableIsUninitialized,
962}
963
964#[cfg(feature = "std")]
965impl std::error::Error for FSEDecoderError {
966    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
967        match self {
968            FSEDecoderError::GetBitsError(source) => Some(source),
969            _ => None,
970        }
971    }
972}
973
974impl core::fmt::Display for FSEDecoderError {
975    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
976        match self {
977            FSEDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
978            FSEDecoderError::TableIsUninitialized => {
979                write!(f, "Tried to use an uninitialized table!")
980            }
981        }
982    }
983}
984
985impl From<GetBitsError> for FSEDecoderError {
986    fn from(val: GetBitsError) -> Self {
987        Self::GetBitsError(val)
988    }
989}
990
991#[derive(Debug)]
992#[non_exhaustive]
993pub enum HuffmanTableError {
994    GetBitsError(GetBitsError),
995    FSEDecoderError(FSEDecoderError),
996    FSETableError(FSETableError),
997    SourceIsEmpty,
998    NotEnoughBytesForWeights {
999        got_bytes: usize,
1000        expected_bytes: u8,
1001    },
1002    ExtraPadding {
1003        skipped_bits: i32,
1004    },
1005    TooManyWeights {
1006        got: usize,
1007    },
1008    MissingWeights,
1009    LeftoverIsNotAPowerOf2 {
1010        got: u32,
1011    },
1012    NotEnoughBytesToDecompressWeights {
1013        have: usize,
1014        need: usize,
1015    },
1016    FSETableUsedTooManyBytes {
1017        used: usize,
1018        available_bytes: u8,
1019    },
1020    NotEnoughBytesInSource {
1021        got: usize,
1022        need: usize,
1023    },
1024    WeightBiggerThanMaxNumBits {
1025        got: u8,
1026    },
1027    MaxBitsTooHigh {
1028        got: u8,
1029    },
1030}
1031
1032#[cfg(feature = "std")]
1033impl StdError for HuffmanTableError {
1034    fn source(&self) -> Option<&(dyn StdError + 'static)> {
1035        match self {
1036            HuffmanTableError::GetBitsError(source) => Some(source),
1037            HuffmanTableError::FSEDecoderError(source) => Some(source),
1038            HuffmanTableError::FSETableError(source) => Some(source),
1039            _ => None,
1040        }
1041    }
1042}
1043
1044impl core::fmt::Display for HuffmanTableError {
1045    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1046        match self {
1047            HuffmanTableError::GetBitsError(e) => write!(f, "{e:?}"),
1048            HuffmanTableError::FSEDecoderError(e) => write!(f, "{e:?}"),
1049            HuffmanTableError::FSETableError(e) => write!(f, "{e:?}"),
1050            HuffmanTableError::SourceIsEmpty => write!(f, "Source needs to have at least one byte"),
1051            HuffmanTableError::NotEnoughBytesForWeights {
1052                got_bytes,
1053                expected_bytes,
1054            } => {
1055                write!(f, "Header says there should be {expected_bytes} bytes for the weights but there are only {got_bytes} bytes in the stream")
1056            }
1057            HuffmanTableError::ExtraPadding { skipped_bits } => {
1058                write!(f,
1059                    "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1060                )
1061            }
1062            HuffmanTableError::TooManyWeights { got } => {
1063                write!(
1064                    f,
1065                    "More than 255 weights decoded (got {got} weights). Stream is probably corrupted",
1066                )
1067            }
1068            HuffmanTableError::MissingWeights => {
1069                write!(f, "Can\'t build huffman table without any weights")
1070            }
1071            HuffmanTableError::LeftoverIsNotAPowerOf2 { got } => {
1072                write!(f, "Leftover must be power of two but is: {got}")
1073            }
1074            HuffmanTableError::NotEnoughBytesToDecompressWeights { have, need } => {
1075                write!(
1076                    f,
1077                    "Not enough bytes in stream to decompress weights. Is: {have}, Should be: {need}",
1078                )
1079            }
1080            HuffmanTableError::FSETableUsedTooManyBytes {
1081                used,
1082                available_bytes,
1083            } => {
1084                write!(f,
1085                    "FSE table used more bytes: {used} than were meant to be used for the whole stream of huffman weights ({available_bytes})",
1086                )
1087            }
1088            HuffmanTableError::NotEnoughBytesInSource { got, need } => {
1089                write!(f, "Source needs to have at least {need} bytes, got: {got}",)
1090            }
1091            HuffmanTableError::WeightBiggerThanMaxNumBits { got } => {
1092                write!(
1093                    f,
1094                    "Cant have weight: {} bigger than max_num_bits: {}",
1095                    got,
1096                    crate::huff0::MAX_MAX_NUM_BITS,
1097                )
1098            }
1099            HuffmanTableError::MaxBitsTooHigh { got } => {
1100                write!(
1101                    f,
1102                    "max_bits derived from weights is: {} should be lower than: {}",
1103                    got,
1104                    crate::huff0::MAX_MAX_NUM_BITS,
1105                )
1106            }
1107        }
1108    }
1109}
1110
1111impl From<GetBitsError> for HuffmanTableError {
1112    fn from(val: GetBitsError) -> Self {
1113        Self::GetBitsError(val)
1114    }
1115}
1116
1117impl From<FSEDecoderError> for HuffmanTableError {
1118    fn from(val: FSEDecoderError) -> Self {
1119        Self::FSEDecoderError(val)
1120    }
1121}
1122
1123impl From<FSETableError> for HuffmanTableError {
1124    fn from(val: FSETableError) -> Self {
1125        Self::FSETableError(val)
1126    }
1127}
1128
1129#[derive(Debug)]
1130#[non_exhaustive]
1131pub enum HuffmanDecoderError {
1132    GetBitsError(GetBitsError),
1133}
1134
1135impl core::fmt::Display for HuffmanDecoderError {
1136    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1137        match self {
1138            HuffmanDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1139        }
1140    }
1141}
1142
1143#[cfg(feature = "std")]
1144impl StdError for HuffmanDecoderError {
1145    fn source(&self) -> Option<&(dyn StdError + 'static)> {
1146        match self {
1147            HuffmanDecoderError::GetBitsError(source) => Some(source),
1148        }
1149    }
1150}
1151
1152impl From<GetBitsError> for HuffmanDecoderError {
1153    fn from(val: GetBitsError) -> Self {
1154        Self::GetBitsError(val)
1155    }
1156}