1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Error type returned by every parser in this crate.
use thiserror::Error;
/// Crate-wide result alias.
pub type Result<T> = core::result::Result<T, Error>;
/// Error variants that parsers + builders can return.
///
/// Spec references inside `#[error(...)]` strings quote clauses from
/// ETSI EN 300 468 v1.19.1 where applicable.
#[derive(Debug, Error, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
/// Input buffer was shorter than the smallest valid encoding for the type.
#[error("buffer too short: need {need} bytes, have {have} (while parsing {what})")]
BufferTooShort {
/// Bytes required to proceed.
need: usize,
/// Bytes actually available.
have: usize,
/// Human-readable name of the type or field being parsed.
what: &'static str,
},
/// CRC-32 validation failed for a table section.
#[error("CRC-32 mismatch: computed {computed:#010x}, expected {expected:#010x}")]
CrcMismatch {
/// CRC we calculated over the section bytes.
computed: u32,
/// CRC carried at the end of the section.
expected: u32,
},
/// `table_id` byte doesn't match any expected value for the parser invoked.
#[error("unexpected table_id {table_id:#04x} for {what} (expected one of {expected:?})")]
UnexpectedTableId {
/// Byte value actually read.
table_id: u8,
/// Table names or parser expecting it.
what: &'static str,
/// The permitted set.
expected: &'static [u8],
},
/// Descriptor payload failed semantic validation.
#[error("invalid descriptor (tag {tag:#04x}): {reason}")]
InvalidDescriptor {
/// Descriptor tag being parsed.
tag: u8,
/// Specific failure reason.
reason: &'static str,
},
/// A decoded value passed to a `set_*` accessor could not be encoded to the
/// field's fixed wire representation (e.g. a duration ≥ 100 hours, or a date
/// outside the 16-bit MJD range).
#[error("value out of range for {field}: {reason}")]
ValueOutOfRange {
/// Field being set.
field: &'static str,
/// Why the value is not representable.
reason: &'static str,
},
/// A `section_length` declared more bytes than the containing buffer could hold.
#[error("section_length {declared} exceeds remaining buffer ({available} bytes)")]
SectionLengthOverflow {
/// Length bytes declared inside the section header.
declared: usize,
/// Bytes actually available after the header.
available: usize,
},
/// A reserved bit was not in the expected state. Most parsers are permissive
/// about reserved bits; this variant is only emitted when a spec clause
/// specifically requires a value.
#[error("reserved bits violation in {field}: {reason}")]
ReservedBitsViolation {
/// Where.
field: &'static str,
/// Why.
reason: &'static str,
},
/// Write buffer passed to `serialize_into` was smaller than `serialized_len()`.
#[error("serialize: output buffer too small — need {need}, have {have}")]
OutputBufferTooSmall {
/// Required size.
need: usize,
/// Actual size.
have: usize,
},
/// TS sync byte was not the expected `0x47`.
#[error("invalid TS sync byte: expected 0x47, got {found:#04x}")]
InvalidSyncByte {
/// The byte actually read at position 0.
found: u8,
},
}
impl From<mpeg_ts::Error> for Error {
fn from(e: mpeg_ts::Error) -> Self {
match e {
mpeg_ts::Error::BufferTooShort { need, have, what } => {
Error::BufferTooShort { need, have, what }
}
mpeg_ts::Error::CrcMismatch { computed, expected } => {
Error::CrcMismatch { computed, expected }
}
mpeg_ts::Error::InvalidSyncByte { found } => Error::InvalidSyncByte { found },
mpeg_ts::Error::OutputBufferTooSmall { need, have } => {
Error::OutputBufferTooSmall { need, have }
}
mpeg_ts::Error::SectionLengthOverflow {
declared,
available,
} => Error::SectionLengthOverflow {
declared,
available,
},
// mpeg_ts::Error is #[non_exhaustive]; catch future variants generically.
_ => Error::BufferTooShort {
need: 0,
have: 0,
what: "mpeg_ts (unknown error)",
},
}
}
}