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    /// Only the metadata schema introduced in craft-codec 0.2.0 is supported.
14    UnsupportedSchemaVersion,
15    /// The metadata requires a compression codec whose feature is disabled.
16    CompressionUnavailable,
17    /// The metadata requires an encryption codec whose feature is disabled.
18    EncryptionUnavailable,
19    /// The logical range is reversed or outside the object.
20    InvalidRange,
21    /// A full frame was submitted after a short final frame.
22    FrameAfterFinal,
23    /// The buffer does not have the expected stored length.
24    InvalidStoredLength,
25    /// The descriptor and the decoder use different configurations.
26    ProfileMismatch,
27    /// The configured cryptographic usage limit was reached.
28    UsageLimit,
29    /// An integer or platform buffer limit would be exceeded.
30    Overflow,
31    /// A buffer or index allocation failed.
32    Allocation,
33    /// The compression operation failed.
34    CompressionFailed,
35    /// Invalid compressed bytes or an incorrect decoded length.
36    DecompressionFailed,
37    /// Encryption failed.
38    EncryptionFailed,
39    /// The frame did not authenticate.
40    AuthenticationFailed,
41}
42
43impl fmt::Display for Error {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        f.write_str(match self {
46            Self::InvalidFrameSize => "invalid or unsupported frame size",
47            Self::InvalidMetadata => "inconsistent frame metadata",
48            Self::UnsupportedVersion => "unsupported metadata version",
49            Self::UnsupportedSchemaVersion => {
50                "unsupported metadata schema; only schema 2 introduced in craft-codec 0.2.0 is supported"
51            }
52            Self::CompressionUnavailable => "required compression codec is not enabled",
53            Self::EncryptionUnavailable => "required encryption codec is not enabled",
54            Self::InvalidRange => "logical range outside the object or reversed",
55            Self::FrameAfterFinal => "frame submitted after a short final frame",
56            Self::InvalidStoredLength => "incorrect stored frame length",
57            Self::ProfileMismatch => "frame and decoder configurations differ",
58            Self::UsageLimit => "cryptographic usage limit exceeded",
59            Self::Overflow => "length exceeds integer or platform limits",
60            Self::Allocation => "buffer allocation failed",
61            Self::CompressionFailed => "compression failed",
62            Self::DecompressionFailed => "invalid compressed frame",
63            Self::EncryptionFailed => "encryption failed",
64            Self::AuthenticationFailed => "frame authentication failed",
65        })
66    }
67}
68
69impl std::error::Error for Error {}
70
71/// Result of a CRAFT operation.
72pub type Result<T> = std::result::Result<T, Error>;
73
74pub(crate) fn buffer_len(len: u64) -> Result<usize> {
75    let len = usize::try_from(len).map_err(|_| Error::Overflow)?;
76    if len > isize::MAX as usize {
77        return Err(Error::Overflow);
78    }
79    Ok(len)
80}
81
82#[cfg(feature = "lz4")]
83pub(crate) fn resize(buffer: &mut Vec<u8>, len: usize) -> Result<()> {
84    if len > isize::MAX as usize {
85        return Err(Error::Overflow);
86    }
87    if len > buffer.len() {
88        let additional = len.checked_sub(buffer.len()).ok_or(Error::Overflow)?;
89        buffer
90            .try_reserve(additional)
91            .map_err(|_| Error::Allocation)?;
92    }
93    buffer.resize(len, 0);
94    Ok(())
95}