Skip to main content

stream_transfer_limit/
error.rs

1use thiserror::Error;
2
3/// Error returned by a transfer-limited stream.
4#[derive(Debug, Error)]
5pub enum TransferLimitError<E, C = usize> {
6    /// The stream produced more bytes than allowed.
7    #[error("transfer size limit exceeded: observed {actual} bytes with a {limit} byte limit")]
8    LimitExceeded {
9        /// Configured maximum number of bytes.
10        limit: C,
11        /// Number of bytes observed after reading the chunk that crossed the limit.
12        actual: C,
13    },
14    /// The cumulative byte count cannot be represented by the selected counter.
15    #[error(
16        "transfer counter overflowed after {bytes_seen} bytes while adding a {chunk_len} byte chunk"
17    )]
18    CounterOverflow {
19        /// Number of bytes counted before reading the chunk that overflowed.
20        bytes_seen: C,
21        /// Byte length of the chunk that could not be added to the counter.
22        chunk_len: usize,
23    },
24    /// The wrapped stream returned an error.
25    #[error("inner stream returned an error")]
26    Inner {
27        /// Original stream error.
28        #[source]
29        source: E,
30    },
31}
32
33impl<E, C> TransferLimitError<E, C> {
34    /// Returns `true` when this error represents an exceeded transfer limit.
35    pub fn is_limit_exceeded(&self) -> bool {
36        matches!(self, Self::LimitExceeded { .. })
37    }
38
39    /// Returns `true` when the selected counter type could not represent the
40    /// cumulative byte count.
41    pub fn is_counter_overflow(&self) -> bool {
42        matches!(self, Self::CounterOverflow { .. })
43    }
44
45    /// Returns the wrapped stream error, if this is an inner stream error.
46    pub fn into_inner(self) -> Option<E> {
47        match self {
48            Self::Inner { source } => Some(source),
49            Self::LimitExceeded { .. } | Self::CounterOverflow { .. } => None,
50        }
51    }
52
53    pub(crate) fn inner(source: E) -> Self {
54        Self::Inner { source }
55    }
56}
57
58impl<E, C> From<E> for TransferLimitError<E, C> {
59    fn from(source: E) -> Self {
60        Self::inner(source)
61    }
62}