dvb_si/descriptors/
bouquet_name.rs1use super::descriptor_body;
4use crate::error::{Error, Result};
5use crate::text::DvbText;
6use dvb_common::{Parse, Serialize};
7
8pub const TAG: u8 = 0x47;
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 BouquetNameDescriptor<'a> {
20 pub bouquet_name: DvbText<'a>,
22}
23
24impl<'a> Parse<'a> for BouquetNameDescriptor<'a> {
25 type Error = crate::error::Error;
26 fn parse(bytes: &'a [u8]) -> Result<Self> {
27 let body = descriptor_body(bytes, TAG, "BouquetNameDescriptor", "expected tag 0x47")?;
28 Ok(BouquetNameDescriptor {
29 bouquet_name: DvbText::new(body),
30 })
31 }
32}
33
34impl Serialize for BouquetNameDescriptor<'_> {
35 type Error = crate::error::Error;
36 fn serialized_len(&self) -> usize {
37 HEADER_LEN + self.bouquet_name.len()
38 }
39
40 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
41 let need = self.serialized_len();
42 if buf.len() < need {
43 return Err(Error::OutputBufferTooSmall {
44 need,
45 have: buf.len(),
46 });
47 }
48
49 buf[0] = TAG;
50 buf[1] = self.bouquet_name.len() as u8;
51 buf[HEADER_LEN..need].copy_from_slice(self.bouquet_name.raw());
52
53 Ok(need)
54 }
55}
56impl<'a> crate::traits::DescriptorDef<'a> for BouquetNameDescriptor<'a> {
57 const TAG: u8 = TAG;
58 const NAME: &'static str = "BOUQUET_NAME";
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
67 fn parse_extracts_bouquet_name() {
68 let raw: Vec<u8> = vec![
69 TAG, 0x04, b'B', b'O', b'U', b'Q',
71 ];
72 let desc = BouquetNameDescriptor::parse(&raw).unwrap();
73 assert_eq!(desc.bouquet_name.raw(), b"BOUQ");
74 }
75
76 #[test]
78 fn parse_rejects_wrong_tag() {
79 let raw: Vec<u8> = vec![
80 0x48, 0x04, b'B', b'O', b'U', b'Q',
82 ];
83 let err = BouquetNameDescriptor::parse(&raw).unwrap_err();
84 assert!(
85 matches!(err, Error::InvalidDescriptor { tag: 0x48, .. }),
86 "expected InvalidDescriptor(tag=0x48), got {err:?}"
87 );
88 }
89
90 #[test]
92 fn parse_rejects_buffer_shorter_than_header() {
93 let raw: &[u8] = &[0x47];
94 let err = BouquetNameDescriptor::parse(raw).unwrap_err();
95 assert!(
96 matches!(err, Error::BufferTooShort { need: 2, .. }),
97 "expected BufferTooShort(need=2), got {err:?}"
98 );
99 }
100
101 #[test]
103 fn parse_rejects_length_overrunning_buffer() {
104 let raw: Vec<u8> = vec![
105 0x47, 0x05, 0xAA, 0xBB, ];
108 let err = BouquetNameDescriptor::parse(&raw).unwrap_err();
109 assert!(matches!(err, Error::BufferTooShort { .. }));
110 }
111
112 #[test]
114 fn empty_bouquet_name_is_valid() {
115 let raw: &[u8] = &[TAG, 0x00];
116 let desc = BouquetNameDescriptor::parse(raw).unwrap();
117 assert!(desc.bouquet_name.raw().is_empty());
118 }
119
120 #[test]
123 fn serialize_round_trip_preserves_bytes() {
124 let raw: Vec<u8> = vec![TAG, 0x04, b'B', b'O', b'U', b'Q'];
125 let parsed = BouquetNameDescriptor::parse(&raw).unwrap();
126 let mut buf = vec![0u8; parsed.serialized_len()];
127 let written = parsed.serialize_into(&mut buf).unwrap();
128 assert_eq!(written, parsed.serialized_len());
129
130 let reparsed = BouquetNameDescriptor::parse(&buf).unwrap();
131 assert_eq!(parsed, reparsed);
132 assert_eq!(&raw, &buf[..]);
133 }
134
135 #[test]
137 fn serialize_rejects_too_small_buffer() {
138 let raw: Vec<u8> = vec![TAG, 0x04, b'B', b'O', b'U', b'Q'];
139 let parsed = BouquetNameDescriptor::parse(&raw).unwrap();
140 let mut tiny = vec![0u8; 1];
141 let err = parsed.serialize_into(&mut tiny).unwrap_err();
142 assert!(
143 matches!(err, Error::OutputBufferTooSmall { need, .. } if need == parsed.serialized_len()),
144 "expected OutputBufferTooSmall(need={}), got {err:?}",
145 parsed.serialized_len()
146 );
147 }
148}