dvb_si/descriptors/
transport_stream.rs1use super::descriptor_body;
10use crate::error::{Error, Result};
11use dvb_common::{Parse, Serialize};
12
13pub const TAG: u8 = 0x67;
15pub const HEADER_LEN: usize = 2;
17
18#[derive(Debug, Clone, PartialEq, Eq)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize))]
21#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
22pub struct TransportStreamDescriptor<'a> {
23 pub bytes: &'a [u8],
25}
26
27impl<'a> Parse<'a> for TransportStreamDescriptor<'a> {
28 type Error = crate::error::Error;
29 fn parse(bytes: &'a [u8]) -> Result<Self> {
30 let body = descriptor_body(
31 bytes,
32 TAG,
33 "TransportStreamDescriptor",
34 "unexpected tag for transport_stream_descriptor",
35 )?;
36 Ok(Self { bytes: body })
37 }
38}
39
40impl Serialize for TransportStreamDescriptor<'_> {
41 type Error = crate::error::Error;
42 fn serialized_len(&self) -> usize {
43 HEADER_LEN + self.bytes.len()
44 }
45
46 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
47 if self.bytes.len() > u8::MAX as usize {
48 return Err(Error::InvalidDescriptor {
49 tag: TAG,
50 reason: "transport_stream_descriptor body exceeds 255 bytes",
51 });
52 }
53 let len = self.serialized_len();
54 if buf.len() < len {
55 return Err(Error::OutputBufferTooSmall {
56 need: len,
57 have: buf.len(),
58 });
59 }
60 buf[0] = TAG;
61 buf[1] = self.bytes.len() as u8;
62 buf[HEADER_LEN..len].copy_from_slice(self.bytes);
63 Ok(len)
64 }
65}
66impl<'a> crate::traits::DescriptorDef<'a> for TransportStreamDescriptor<'a> {
67 const TAG: u8 = TAG;
68 const NAME: &'static str = "TRANSPORT_STREAM";
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn parse_extracts_dvb_marker() {
77 let bytes = [TAG, 3, b'D', b'V', b'B'];
78 let d = TransportStreamDescriptor::parse(&bytes).unwrap();
79 assert_eq!(d.bytes, b"DVB");
80 }
81
82 #[test]
83 fn empty_body_is_valid() {
84 let bytes = [TAG, 0];
85 let d = TransportStreamDescriptor::parse(&bytes).unwrap();
86 assert!(d.bytes.is_empty());
87 }
88
89 #[test]
90 fn parse_rejects_wrong_tag() {
91 assert!(matches!(
92 TransportStreamDescriptor::parse(&[0x68, 0]).unwrap_err(),
93 Error::InvalidDescriptor { tag: 0x68, .. }
94 ));
95 }
96
97 #[test]
98 fn parse_rejects_short_header() {
99 assert!(matches!(
100 TransportStreamDescriptor::parse(&[TAG]).unwrap_err(),
101 Error::BufferTooShort { .. }
102 ));
103 }
104
105 #[test]
106 fn parse_rejects_length_overrunning_buffer() {
107 let bytes = [TAG, 5, 1, 2, 3];
108 assert!(matches!(
109 TransportStreamDescriptor::parse(&bytes).unwrap_err(),
110 Error::BufferTooShort { .. }
111 ));
112 }
113
114 #[test]
115 fn serialize_round_trip() {
116 let d = TransportStreamDescriptor { bytes: b"DVB" };
117 let mut buf = vec![0u8; d.serialized_len()];
118 d.serialize_into(&mut buf).unwrap();
119 assert_eq!(TransportStreamDescriptor::parse(&buf).unwrap(), d);
120 }
121
122 #[test]
123 fn serialize_rejects_too_small_buffer() {
124 let d = TransportStreamDescriptor { bytes: b"DVB" };
125 let mut buf = vec![0u8; 1];
126 assert!(matches!(
127 d.serialize_into(&mut buf).unwrap_err(),
128 Error::OutputBufferTooSmall { .. }
129 ));
130 }
131
132 #[test]
133 fn serialize_rejects_over_range_body() {
134 let big = vec![0u8; 256];
135 let d = TransportStreamDescriptor { bytes: &big };
136 let mut buf = vec![0u8; d.serialized_len()];
137 assert!(matches!(
138 d.serialize_into(&mut buf).unwrap_err(),
139 Error::InvalidDescriptor { tag: TAG, .. }
140 ));
141 }
142
143 }