dvb_si/descriptors/
dsng.rs1use crate::error::{Error, Result};
9use crate::traits::Descriptor;
10use dvb_common::{Parse, Serialize};
11
12pub const TAG: u8 = 0x68;
14pub const HEADER_LEN: usize = 2;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize))]
20pub struct DsngDescriptor<'a> {
21 pub bytes: &'a [u8],
23}
24
25impl<'a> Parse<'a> for DsngDescriptor<'a> {
26 type Error = crate::error::Error;
27 fn parse(bytes: &'a [u8]) -> Result<Self> {
28 if bytes.len() < HEADER_LEN {
29 return Err(Error::BufferTooShort {
30 need: HEADER_LEN,
31 have: bytes.len(),
32 what: "DsngDescriptor header",
33 });
34 }
35 if bytes[0] != TAG {
36 return Err(Error::InvalidDescriptor {
37 tag: bytes[0],
38 reason: "unexpected tag for DSNG_descriptor",
39 });
40 }
41 let length = bytes[1] as usize;
42 let end = HEADER_LEN + length;
43 if bytes.len() < end {
44 return Err(Error::BufferTooShort {
45 need: end,
46 have: bytes.len(),
47 what: "DsngDescriptor body",
48 });
49 }
50 Ok(Self {
51 bytes: &bytes[HEADER_LEN..end],
52 })
53 }
54}
55
56impl Serialize for DsngDescriptor<'_> {
57 type Error = crate::error::Error;
58 fn serialized_len(&self) -> usize {
59 HEADER_LEN + self.bytes.len()
60 }
61
62 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
63 if self.bytes.len() > u8::MAX as usize {
64 return Err(Error::InvalidDescriptor {
65 tag: TAG,
66 reason: "DSNG_descriptor body exceeds 255 bytes",
67 });
68 }
69 let len = self.serialized_len();
70 if buf.len() < len {
71 return Err(Error::OutputBufferTooSmall {
72 need: len,
73 have: buf.len(),
74 });
75 }
76 buf[0] = TAG;
77 buf[1] = self.bytes.len() as u8;
78 buf[HEADER_LEN..len].copy_from_slice(self.bytes);
79 Ok(len)
80 }
81}
82
83impl<'a> Descriptor<'a> for DsngDescriptor<'a> {
84 const TAG: u8 = TAG;
85 fn descriptor_length(&self) -> u8 {
86 self.bytes.len() as u8
87 }
88}
89
90impl<'a> crate::traits::DescriptorDef<'a> for DsngDescriptor<'a> {
91 const TAG: u8 = TAG;
92 const NAME: &'static str = "DSNG";
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn parse_extracts_ascii() {
101 let bytes = [TAG, 4, b'D', b'S', b'N', b'G'];
102 let d = DsngDescriptor::parse(&bytes).unwrap();
103 assert_eq!(d.bytes, b"DSNG");
104 }
105
106 #[test]
107 fn empty_body_is_valid() {
108 let bytes = [TAG, 0];
109 let d = DsngDescriptor::parse(&bytes).unwrap();
110 assert!(d.bytes.is_empty());
111 }
112
113 #[test]
114 fn parse_rejects_wrong_tag() {
115 assert!(matches!(
116 DsngDescriptor::parse(&[0x69, 0]).unwrap_err(),
117 Error::InvalidDescriptor { tag: 0x69, .. }
118 ));
119 }
120
121 #[test]
122 fn parse_rejects_short_header() {
123 assert!(matches!(
124 DsngDescriptor::parse(&[TAG]).unwrap_err(),
125 Error::BufferTooShort { .. }
126 ));
127 }
128
129 #[test]
130 fn parse_rejects_length_overrunning_buffer() {
131 let bytes = [TAG, 5, 1, 2, 3];
132 assert!(matches!(
133 DsngDescriptor::parse(&bytes).unwrap_err(),
134 Error::BufferTooShort { .. }
135 ));
136 }
137
138 #[test]
139 fn serialize_round_trip() {
140 let d = DsngDescriptor {
141 bytes: b"News Truck 4",
142 };
143 let mut buf = vec![0u8; d.serialized_len()];
144 d.serialize_into(&mut buf).unwrap();
145 assert_eq!(DsngDescriptor::parse(&buf).unwrap(), d);
146 }
147
148 #[test]
149 fn serialize_rejects_too_small_buffer() {
150 let d = DsngDescriptor { bytes: b"DSNG" };
151 let mut buf = vec![0u8; 1];
152 assert!(matches!(
153 d.serialize_into(&mut buf).unwrap_err(),
154 Error::OutputBufferTooSmall { .. }
155 ));
156 }
157
158 #[test]
159 fn serialize_rejects_over_range_body() {
160 let big = vec![0u8; 256];
161 let d = DsngDescriptor { bytes: &big };
162 let mut buf = vec![0u8; d.serialized_len()];
163 assert!(matches!(
164 d.serialize_into(&mut buf).unwrap_err(),
165 Error::InvalidDescriptor { tag: TAG, .. }
166 ));
167 }
168
169 }