dvb_si/descriptors/
network_name.rs1use crate::error::{Error, Result};
4use crate::text::DvbText;
5use crate::traits::Descriptor;
6use dvb_common::{Parse, Serialize};
7
8pub const TAG: u8 = 0x40;
10
11pub const HEADER_LEN: usize = 2;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
18#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
19pub struct NetworkNameDescriptor<'a> {
20 pub network_name: DvbText<'a>,
22}
23
24impl<'a> Parse<'a> for NetworkNameDescriptor<'a> {
25 type Error = crate::error::Error;
26 fn parse(bytes: &'a [u8]) -> Result<Self> {
27 if bytes.len() < HEADER_LEN {
28 return Err(Error::BufferTooShort {
29 need: HEADER_LEN,
30 have: bytes.len(),
31 what: "network name descriptor header",
32 });
33 }
34
35 let tag = bytes[0];
36 if tag != TAG {
37 return Err(Error::InvalidDescriptor {
38 tag,
39 reason: "expected tag 0x40",
40 });
41 }
42
43 let length = bytes[1] as usize;
44 let total = HEADER_LEN + length;
45
46 if bytes.len() < total {
47 return Err(Error::BufferTooShort {
48 need: total,
49 have: bytes.len(),
50 what: "network name descriptor payload",
51 });
52 }
53
54 Ok(NetworkNameDescriptor {
55 network_name: DvbText::new(&bytes[HEADER_LEN..total]),
56 })
57 }
58}
59
60impl Serialize for NetworkNameDescriptor<'_> {
61 type Error = crate::error::Error;
62 fn serialized_len(&self) -> usize {
63 HEADER_LEN + self.network_name.len()
64 }
65
66 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
67 let need = self.serialized_len();
68 if buf.len() < need {
69 return Err(Error::OutputBufferTooSmall {
70 need,
71 have: buf.len(),
72 });
73 }
74
75 buf[0] = TAG;
76 buf[1] = self.network_name.len() as u8;
77 buf[HEADER_LEN..need].copy_from_slice(self.network_name.raw());
78
79 Ok(need)
80 }
81}
82
83impl<'a> Descriptor<'a> for NetworkNameDescriptor<'a> {
84 const TAG: u8 = 0x40;
85
86 fn descriptor_length(&self) -> u8 {
87 self.network_name.raw().len() as u8
88 }
89}
90
91impl<'a> crate::traits::DescriptorDef<'a> for NetworkNameDescriptor<'a> {
92 const TAG: u8 = TAG;
93 const NAME: &'static str = "NETWORK_NAME";
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
102 fn parse_extracts_network_name() {
103 let raw: Vec<u8> = vec![
104 TAG, 0x04, b'E', b'U', b'T', b'E',
106 ];
107 let desc = NetworkNameDescriptor::parse(&raw).unwrap();
108 assert_eq!(desc.network_name.raw(), b"EUTE");
109 }
110
111 #[test]
113 fn parse_rejects_wrong_tag() {
114 let raw: Vec<u8> = vec![
115 0x41, 0x04, b'E', b'U', b'T', b'E',
117 ];
118 let err = NetworkNameDescriptor::parse(&raw).unwrap_err();
119 assert!(
120 matches!(err, Error::InvalidDescriptor { tag: 0x41, .. }),
121 "expected InvalidDescriptor(tag=0x41), got {err:?}"
122 );
123 }
124
125 #[test]
127 fn parse_rejects_buffer_shorter_than_header() {
128 let raw: &[u8] = &[0x40];
129 let err = NetworkNameDescriptor::parse(raw).unwrap_err();
130 assert!(
131 matches!(err, Error::BufferTooShort { need: 2, .. }),
132 "expected BufferTooShort(need=2), got {err:?}"
133 );
134 }
135
136 #[test]
138 fn parse_rejects_length_byte_overflowing_buffer() {
139 let raw: Vec<u8> = vec![
140 0x40, 0x05, 0xAA, 0xBB, ];
143 let err = NetworkNameDescriptor::parse(&raw).unwrap_err();
144 assert!(matches!(err, Error::BufferTooShort { .. }));
145 }
146
147 #[test]
150 fn serialize_round_trip_preserves_bytes() {
151 let raw: Vec<u8> = vec![TAG, 0x04, b'E', b'U', b'T', b'E'];
152 let parsed = NetworkNameDescriptor::parse(&raw).unwrap();
153 let mut buf = vec![0u8; parsed.serialized_len()];
154 let written = parsed.serialize_into(&mut buf).unwrap();
155 assert_eq!(written, parsed.serialized_len());
156
157 let reparsed = NetworkNameDescriptor::parse(&buf).unwrap();
158 assert_eq!(parsed, reparsed);
159 assert_eq!(&raw, &buf[..]);
160 }
161
162 #[test]
164 fn serialize_rejects_too_small_buffer() {
165 let raw: Vec<u8> = vec![TAG, 0x04, b'E', b'U', b'T', b'E'];
166 let parsed = NetworkNameDescriptor::parse(&raw).unwrap();
167 let mut tiny = vec![0u8; 1];
168 let err = parsed.serialize_into(&mut tiny).unwrap_err();
169 assert!(
170 matches!(err, Error::OutputBufferTooSmall { need, .. } if need == parsed.serialized_len()),
171 "expected OutputBufferTooSmall(need={}), got {err:?}",
172 parsed.serialized_len()
173 );
174 }
175
176 #[test]
178 fn empty_network_name_is_valid() {
179 let raw: &[u8] = &[TAG, 0x00];
180 let desc = NetworkNameDescriptor::parse(raw).unwrap();
181 assert!(desc.network_name.raw().is_empty());
182 }
183
184 #[test]
186 fn descriptor_length_getter_matches_payload() {
187 let raw: Vec<u8> = vec![TAG, 0x07, b'F', b'R', b'A', b'N', b'C', b'E', b'2'];
188 let desc = NetworkNameDescriptor::parse(&raw).unwrap();
189 assert_eq!(
190 desc.descriptor_length(),
191 desc.network_name.raw().len() as u8
192 );
193 }
194}