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)]
13pub enum Error {
14 /// Input buffer was shorter than the smallest valid encoding for the type.
15 #[error("buffer too short: need {need} bytes, have {have} (while parsing {what})")]
16 BufferTooShort {
17 /// Bytes required to proceed.
18 need: usize,
19 /// Bytes actually available.
20 have: usize,
21 /// Human-readable name of the type or field being parsed.
22 what: &'static str,
23 },
24
25 /// CRC-32 validation failed for a table section.
26 #[error("CRC-32 mismatch: computed {computed:#010x}, expected {expected:#010x}")]
27 CrcMismatch {
28 /// CRC we calculated over the section bytes.
29 computed: u32,
30 /// CRC carried at the end of the section.
31 expected: u32,
32 },
33
34 /// `table_id` byte doesn't match any expected value for the parser invoked.
35 #[error("unexpected table_id {table_id:#04x} for {what} (expected one of {expected:?})")]
36 UnexpectedTableId {
37 /// Byte value actually read.
38 table_id: u8,
39 /// Table names or parser expecting it.
40 what: &'static str,
41 /// The permitted set.
42 expected: &'static [u8],
43 },
44
45 /// Descriptor payload failed semantic validation.
46 #[error("invalid descriptor (tag {tag:#04x}): {reason}")]
47 InvalidDescriptor {
48 /// Descriptor tag being parsed.
49 tag: u8,
50 /// Specific failure reason.
51 reason: &'static str,
52 },
53
54 /// BCD-encoded value is out of valid range.
55 #[error("invalid BCD in {field}: bytes {bytes:02x?}")]
56 InvalidBcd {
57 /// Field name where the BCD sits.
58 field: &'static str,
59 /// The (up to 4) raw bytes inspected.
60 bytes: [u8; 4],
61 },
62
63 /// A decoded value passed to a `set_*` accessor could not be encoded to the
64 /// field's fixed wire representation (e.g. a duration ≥ 100 hours, or a date
65 /// outside the 16-bit MJD range).
66 #[error("value out of range for {field}: {reason}")]
67 ValueOutOfRange {
68 /// Field being set.
69 field: &'static str,
70 /// Why the value is not representable.
71 reason: &'static str,
72 },
73
74 /// A `section_length` declared more bytes than the containing buffer could hold.
75 #[error("section_length {declared} exceeds remaining buffer ({available} bytes)")]
76 SectionLengthOverflow {
77 /// Length bytes declared inside the section header.
78 declared: usize,
79 /// Bytes actually available after the header.
80 available: usize,
81 },
82
83 /// A reserved bit was not in the expected state. Most parsers are permissive
84 /// about reserved bits; this variant is only emitted when a spec clause
85 /// specifically requires a value.
86 #[error("reserved bits violation in {field}: {reason}")]
87 ReservedBitsViolation {
88 /// Where.
89 field: &'static str,
90 /// Why.
91 reason: &'static str,
92 },
93
94 /// Write buffer passed to `serialize_into` was smaller than `serialized_len()`.
95 #[error("serialize: output buffer too small — need {need}, have {have}")]
96 OutputBufferTooSmall {
97 /// Required size.
98 need: usize,
99 /// Actual size.
100 have: usize,
101 },
102
103 /// TS sync byte was not the expected `0x47`.
104 #[error("invalid TS sync byte: expected 0x47, got {found:#04x}")]
105 InvalidSyncByte {
106 /// The byte actually read at position 0.
107 found: u8,
108 },
109}