dvb_si/descriptors/
adaptation_field_data.rs1use super::descriptor_body;
8use crate::error::{Error, Result};
9use dvb_common::{Parse, Serialize};
10
11pub const TAG: u8 = 0x70;
13pub const HEADER_LEN: usize = 2;
15pub const BODY_LEN: usize = 1;
17
18const ANNOUNCEMENT_SWITCHING_DATA: u8 = 1 << 0;
20const AU_INFORMATION: u8 = 1 << 1;
21const PVR_ASSIST_INFORMATION: u8 = 1 << 2;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct AdaptationFieldDataFlags {
29 pub announcement_switching_data: bool,
31 pub au_information: bool,
33 pub pvr_assist_information: bool,
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39#[cfg_attr(feature = "serde", derive(serde::Serialize))]
40pub struct AdaptationFieldDataDescriptor {
41 pub adaptation_field_data_identifier: u8,
43}
44
45impl AdaptationFieldDataDescriptor {
46 #[must_use]
49 pub fn flags(&self) -> AdaptationFieldDataFlags {
50 let b = self.adaptation_field_data_identifier;
51 AdaptationFieldDataFlags {
52 announcement_switching_data: (b & ANNOUNCEMENT_SWITCHING_DATA) != 0,
53 au_information: (b & AU_INFORMATION) != 0,
54 pvr_assist_information: (b & PVR_ASSIST_INFORMATION) != 0,
55 }
56 }
57}
58
59impl<'a> Parse<'a> for AdaptationFieldDataDescriptor {
60 type Error = crate::error::Error;
61 fn parse(bytes: &'a [u8]) -> Result<Self> {
62 let body = descriptor_body(
63 bytes,
64 TAG,
65 "AdaptationFieldDataDescriptor",
66 "unexpected tag for adaptation_field_data_descriptor",
67 )?;
68 if body.len() != BODY_LEN {
69 return Err(Error::InvalidDescriptor {
70 tag: TAG,
71 reason: "adaptation_field_data_descriptor length must be exactly 1",
72 });
73 }
74 Ok(Self {
75 adaptation_field_data_identifier: body[0],
76 })
77 }
78}
79
80impl Serialize for AdaptationFieldDataDescriptor {
81 type Error = crate::error::Error;
82 fn serialized_len(&self) -> usize {
83 HEADER_LEN + BODY_LEN
84 }
85
86 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
87 let len = self.serialized_len();
88 if buf.len() < len {
89 return Err(Error::OutputBufferTooSmall {
90 need: len,
91 have: buf.len(),
92 });
93 }
94 buf[0] = TAG;
95 buf[1] = BODY_LEN as u8;
96 buf[HEADER_LEN] = self.adaptation_field_data_identifier;
97 Ok(len)
98 }
99}
100impl<'a> crate::traits::DescriptorDef<'a> for AdaptationFieldDataDescriptor {
101 const TAG: u8 = TAG;
102 const NAME: &'static str = "ADAPTATION_FIELD_DATA";
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn parse_extracts_identifier() {
111 let bytes = [TAG, 1, 0x07];
112 let d = AdaptationFieldDataDescriptor::parse(&bytes).unwrap();
113 assert_eq!(d.adaptation_field_data_identifier, 0x07);
114 }
115
116 #[test]
117 fn flags_decode_all_set() {
118 let d = AdaptationFieldDataDescriptor {
120 adaptation_field_data_identifier: 0x07,
121 };
122 let f = d.flags();
123 assert!(f.announcement_switching_data);
124 assert!(f.au_information);
125 assert!(f.pvr_assist_information);
126 }
127
128 #[test]
129 fn flags_decode_none_set() {
130 let d = AdaptationFieldDataDescriptor {
131 adaptation_field_data_identifier: 0x00,
132 };
133 let f = d.flags();
134 assert!(!f.announcement_switching_data);
135 assert!(!f.au_information);
136 assert!(!f.pvr_assist_information);
137 }
138
139 #[test]
140 fn flags_decode_au_only() {
141 let d = AdaptationFieldDataDescriptor {
143 adaptation_field_data_identifier: 0x02,
144 };
145 let f = d.flags();
146 assert!(!f.announcement_switching_data);
147 assert!(f.au_information);
148 assert!(!f.pvr_assist_information);
149 }
150
151 #[test]
152 fn flags_decode_pvr_only() {
153 let d = AdaptationFieldDataDescriptor {
155 adaptation_field_data_identifier: 0x04,
156 };
157 let f = d.flags();
158 assert!(!f.announcement_switching_data);
159 assert!(!f.au_information);
160 assert!(f.pvr_assist_information);
161 }
162
163 #[test]
164 fn parse_rejects_wrong_tag() {
165 assert!(matches!(
166 AdaptationFieldDataDescriptor::parse(&[0x71, 1, 0]).unwrap_err(),
167 Error::InvalidDescriptor { tag: 0x71, .. }
168 ));
169 }
170
171 #[test]
172 fn parse_rejects_wrong_length() {
173 assert!(matches!(
174 AdaptationFieldDataDescriptor::parse(&[TAG, 0]).unwrap_err(),
175 Error::InvalidDescriptor { tag: TAG, .. }
176 ));
177 }
178
179 #[test]
180 fn parse_rejects_short_body() {
181 assert!(matches!(
182 AdaptationFieldDataDescriptor::parse(&[TAG, 1]).unwrap_err(),
183 Error::BufferTooShort { .. }
184 ));
185 }
186
187 #[test]
188 fn serialize_round_trip() {
189 let d = AdaptationFieldDataDescriptor {
190 adaptation_field_data_identifier: 0x05,
191 };
192 let mut buf = vec![0u8; d.serialized_len()];
193 d.serialize_into(&mut buf).unwrap();
194 assert_eq!(buf, [TAG, 1, 0x05]);
195 assert_eq!(AdaptationFieldDataDescriptor::parse(&buf).unwrap(), d);
196 }
197
198 #[test]
199 fn serialize_rejects_too_small_buffer() {
200 let d = AdaptationFieldDataDescriptor {
201 adaptation_field_data_identifier: 0,
202 };
203 let mut buf = vec![0u8; 2];
204 assert!(matches!(
205 d.serialize_into(&mut buf).unwrap_err(),
206 Error::OutputBufferTooSmall { .. }
207 ));
208 }
209
210 #[cfg(feature = "serde")]
211 #[test]
212 fn serde_round_trip() {
213 let d = AdaptationFieldDataDescriptor {
214 adaptation_field_data_identifier: 0x05,
215 };
216 let json = serde_json::to_string(&d).unwrap();
217 let _v: serde_json::Value = serde_json::from_str(&json).unwrap();
219 }
220}