Skip to main content

oxideav_core/
error.rs

1//! Shared error type for oxideav.
2
3use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Debug, Error)]
8pub enum Error {
9    #[error("I/O error: {0}")]
10    Io(#[from] std::io::Error),
11
12    #[error("unsupported: {0}")]
13    Unsupported(String),
14
15    #[error("invalid data: {0}")]
16    InvalidData(String),
17
18    #[error("end of stream")]
19    Eof,
20
21    #[error("need more data")]
22    NeedMore,
23
24    #[error("format not found: {0}")]
25    FormatNotFound(String),
26
27    #[error("codec not found: {0}")]
28    CodecNotFound(String),
29
30    /// A decoder (or arena pool) refused to allocate or proceed because
31    /// doing so would exceed a configured [`DecoderLimits`](crate::DecoderLimits)
32    /// cap, or because a pool has no free slot. This is the canonical
33    /// "DoS protection fired" error — callers should treat it as a hard
34    /// rejection of the input or a transient backpressure signal, never
35    /// retry blindly.
36    #[error("resource exhausted: {0}")]
37    ResourceExhausted(String),
38
39    #[error("{0}")]
40    Other(String),
41}
42
43impl Error {
44    pub fn unsupported(msg: impl Into<String>) -> Self {
45        Self::Unsupported(msg.into())
46    }
47
48    pub fn invalid(msg: impl Into<String>) -> Self {
49        Self::InvalidData(msg.into())
50    }
51
52    pub fn other(msg: impl Into<String>) -> Self {
53        Self::Other(msg.into())
54    }
55
56    /// Construct a [`Error::ResourceExhausted`] with the given message.
57    /// Use this from any decoder that has just hit a `DecoderLimits` cap
58    /// or an arena-pool exhaustion.
59    pub fn resource_exhausted(msg: impl Into<String>) -> Self {
60        Self::ResourceExhausted(msg.into())
61    }
62}