Skip to main content

craft_codec/
error.rs

1use std::fmt;
2
3/// A format, resource, or transformation failure. No I/O is performed by CRAFT.
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5#[non_exhaustive]
6pub enum Error {
7    /// A zero or unsupported maximum frame length.
8    InvalidFrameSize,
9    /// A length, count, profile, or index is inconsistent.
10    InvalidMetadata,
11    /// This metadata format version is not supported.
12    UnsupportedVersion,
13    /// The logical range is reversed or outside the object.
14    InvalidRange,
15    /// A full frame was submitted after a short final frame.
16    FrameAfterFinal,
17    /// The buffer does not have the expected stored length.
18    InvalidStoredLength,
19    /// The descriptor and the decoder use different configurations.
20    ProfileMismatch,
21    /// The configured cryptographic usage limit was reached.
22    UsageLimit,
23    /// An integer or platform buffer limit would be exceeded.
24    Overflow,
25    /// A buffer or index allocation failed.
26    Allocation,
27    /// The compression operation failed.
28    CompressionFailed,
29    /// Invalid compressed bytes or an incorrect decoded length.
30    DecompressionFailed,
31    /// Encryption failed.
32    EncryptionFailed,
33    /// The frame did not authenticate.
34    AuthenticationFailed,
35}
36
37impl fmt::Display for Error {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        f.write_str(match self {
40            Self::InvalidFrameSize => "invalid or unsupported frame size",
41            Self::InvalidMetadata => "inconsistent frame metadata",
42            Self::UnsupportedVersion => "unsupported metadata version",
43            Self::InvalidRange => "logical range outside the object or reversed",
44            Self::FrameAfterFinal => "frame submitted after a short final frame",
45            Self::InvalidStoredLength => "incorrect stored frame length",
46            Self::ProfileMismatch => "frame and decoder configurations differ",
47            Self::UsageLimit => "cryptographic usage limit exceeded",
48            Self::Overflow => "length exceeds integer or platform limits",
49            Self::Allocation => "buffer allocation failed",
50            Self::CompressionFailed => "compression failed",
51            Self::DecompressionFailed => "invalid compressed frame",
52            Self::EncryptionFailed => "encryption failed",
53            Self::AuthenticationFailed => "frame authentication failed",
54        })
55    }
56}
57
58impl std::error::Error for Error {}
59
60/// Result of a CRAFT operation.
61pub type Result<T> = std::result::Result<T, Error>;
62
63pub(crate) fn buffer_len(len: u64) -> Result<usize> {
64    let len = usize::try_from(len).map_err(|_| Error::Overflow)?;
65    if len > isize::MAX as usize {
66        return Err(Error::Overflow);
67    }
68    Ok(len)
69}
70
71#[cfg(feature = "lz4")]
72pub(crate) fn resize(buffer: &mut Vec<u8>, len: usize) -> Result<()> {
73    if len > isize::MAX as usize {
74        return Err(Error::Overflow);
75    }
76    if len > buffer.len() {
77        buffer
78            .try_reserve(len - buffer.len())
79            .map_err(|_| Error::Allocation)?;
80    }
81    buffer.resize(len, 0);
82    Ok(())
83}