Skip to main content

cadmpeg_core/
error.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Errors returned by codec parsing and resource enforcement.
3
4use crate::decode::{ErrorContext, ResourceLimit, SourceLocation};
5
6/// Errors a codec can raise.
7///
8/// Marked `#[non_exhaustive]`: external exhaustive matches must carry a
9/// wildcard arm.
10#[derive(Debug, thiserror::Error)]
11#[non_exhaustive]
12pub enum CodecError {
13    /// The bytes are not this codec's format.
14    #[error("not the expected format: {0}")]
15    WrongFormat(String),
16    /// The container was structurally malformed.
17    #[error("malformed container: {0}")]
18    Malformed(String),
19    /// A required read extended past the end of its window after commitment.
20    ///
21    /// Distinct from [`CodecError::Malformed`]: a truncation is missing input,
22    /// not an inconsistency inside the bytes that are present.
23    #[error(
24        "truncated input during {} at space {} offset {}",
25        .context.operation, .location.space.index(), .location.offset
26    )]
27    Truncated {
28        /// Where the truncated read began.
29        location: SourceLocation,
30        /// Static context for the failure.
31        context: ErrorContext,
32    },
33    /// A resource limit refused the decode: policy or the allocator.
34    ///
35    /// Never reported as [`CodecError::Malformed`]: a budget refusal is a
36    /// statement about policy, not about the input.
37    #[error(
38        "resource limit on {:?}: {:?} (limit {}, used {}, requested {})",
39        .0.dimension, .0.reason, .0.limit, .0.used, .0.additional
40    )]
41    ResourceLimit(ResourceLimit),
42    /// The codec does not implement a required capability.
43    #[error("not implemented yet: {0}")]
44    NotImplemented(String),
45    /// Underlying I/O failure.
46    #[error("io error: {0}")]
47    Io(#[from] std::io::Error),
48}
49
50impl CodecError {
51    /// Builds a truncation error at a qualified source location.
52    pub const fn truncated(location: SourceLocation, operation: &'static str) -> Self {
53        Self::Truncated {
54            location,
55            context: ErrorContext {
56                operation,
57                location: Some(location),
58            },
59        }
60    }
61}