Skip to main content

dvb_si/
error.rs

1//! Error type returned by every parser in this crate.
2
3use thiserror::Error;
4
5/// Crate-wide result alias.
6pub type Result<T> = core::result::Result<T, Error>;
7
8/// Error variants that parsers + builders can return.
9///
10/// Spec references inside `#[error(...)]` strings quote clauses from
11/// ETSI EN 300 468 v1.19.1 where applicable.
12#[derive(Debug, Error, PartialEq, Eq, Clone)]
13#[non_exhaustive]
14pub enum Error {
15    /// Input buffer was shorter than the smallest valid encoding for the type.
16    #[error(transparent)]
17    BufferTooShort(#[from] broadcast_common::error::BufferTooShort),
18
19    /// CRC-32 validation failed for a table section.
20    #[error(transparent)]
21    CrcMismatch(#[from] broadcast_common::error::CrcMismatch),
22
23    /// `table_id` byte doesn't match any expected value for the parser invoked.
24    #[error("unexpected table_id {table_id:#04x} for {what} (expected one of {expected:?})")]
25    UnexpectedTableId {
26        /// Byte value actually read.
27        table_id: u8,
28        /// Table names or parser expecting it.
29        what: &'static str,
30        /// The permitted set.
31        expected: &'static [u8],
32    },
33
34    /// Descriptor payload failed semantic validation.
35    #[error("invalid descriptor (tag {tag:#04x}): {reason}")]
36    InvalidDescriptor {
37        /// Descriptor tag being parsed.
38        tag: u8,
39        /// Specific failure reason.
40        reason: &'static str,
41    },
42
43    /// A decoded value passed to a `set_*` accessor could not be encoded to the
44    /// field's fixed wire representation (e.g. a duration ≥ 100 hours, or a date
45    /// outside the 16-bit MJD range).
46    #[error("value out of range for {field}: {reason}")]
47    ValueOutOfRange {
48        /// Field being set.
49        field: &'static str,
50        /// Why the value is not representable.
51        reason: &'static str,
52    },
53
54    /// A `section_length` declared more bytes than the containing buffer could hold.
55    #[error("section_length {declared} exceeds remaining buffer ({available} bytes)")]
56    SectionLengthOverflow {
57        /// Length bytes declared inside the section header.
58        declared: usize,
59        /// Bytes actually available after the header.
60        available: usize,
61    },
62
63    /// A reserved or fixed-value bit group was not in the state a spec clause
64    /// requires. Most parsers are permissive about reserved bits; this is only
65    /// emitted when a clause specifically requires a value.
66    #[error(transparent)]
67    ReservedBits(#[from] broadcast_common::error::ReservedBits),
68
69    /// A field held a value its spec clause forbids.
70    #[error(transparent)]
71    InvalidValue(#[from] broadcast_common::error::InvalidValue),
72
73    /// A field is structurally invalid with no single offending number.
74    #[error(transparent)]
75    InvalidField(#[from] broadcast_common::error::InvalidField),
76
77    /// Write buffer passed to `serialize_into` was smaller than `serialized_len()`.
78    #[error(transparent)]
79    OutputBufferTooSmall(#[from] broadcast_common::error::OutputBufferTooSmall),
80
81    /// A fixed marker did not match (TS sync byte, expected `0x47`).
82    #[error(transparent)]
83    InvalidSync(#[from] broadcast_common::error::InvalidSync),
84
85    /// A serializer's length or count value did not fit its wire field.
86    /// Returned instead of silently narrowing (`as u8`/`as u16`/masking),
87    /// which would emit a misframed section (see #1129).
88    #[error(transparent)]
89    FieldOverflow(#[from] broadcast_common::len::FieldOverflow),
90}
91
92impl From<mpeg_ts::Error> for Error {
93    fn from(e: mpeg_ts::Error) -> Self {
94        match e {
95            mpeg_ts::Error::BufferTooShort(e) => Error::BufferTooShort(e),
96            mpeg_ts::Error::CrcMismatch(e) => Error::CrcMismatch(e),
97            mpeg_ts::Error::InvalidSync(e) => Error::InvalidSync(e),
98            mpeg_ts::Error::OutputBufferTooSmall(e) => Error::OutputBufferTooSmall(e),
99            mpeg_ts::Error::SectionLengthOverflow {
100                declared,
101                available,
102            } => Error::SectionLengthOverflow {
103                declared,
104                available,
105            },
106            // mpeg_ts::Error is #[non_exhaustive]; catch future variants generically.
107            _ => Error::BufferTooShort(broadcast_common::error::BufferTooShort {
108                need: 0,
109                have: 0,
110                what: "mpeg_ts (unknown error)",
111            }),
112        }
113    }
114}