1use super::descriptor_body;
6use crate::error::{Error, Result};
7use dvb_common::{Parse, Serialize};
8
9pub const TAG: u8 = 0x1E;
11const HEADER_LEN: usize = 2;
12const BODY_LEN: u8 = 2;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize))]
17pub struct SlDescriptor {
18 pub es_id: u16,
20}
21
22impl<'a> Parse<'a> for SlDescriptor {
23 type Error = crate::error::Error;
24
25 fn parse(bytes: &'a [u8]) -> Result<Self> {
26 let body = descriptor_body(
27 bytes,
28 TAG,
29 "SlDescriptor",
30 "unexpected tag for SL_descriptor",
31 )?;
32 if body.len() != BODY_LEN as usize {
33 return Err(Error::InvalidDescriptor {
34 tag: TAG,
35 reason: "SL_descriptor length must equal 2",
36 });
37 }
38 Ok(Self {
39 es_id: u16::from_be_bytes([body[0], body[1]]),
40 })
41 }
42}
43
44impl Serialize for SlDescriptor {
45 type Error = crate::error::Error;
46
47 fn serialized_len(&self) -> usize {
48 HEADER_LEN + BODY_LEN as usize
49 }
50
51 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
52 let len = self.serialized_len();
53 if buf.len() < len {
54 return Err(Error::OutputBufferTooSmall {
55 need: len,
56 have: buf.len(),
57 });
58 }
59 buf[0] = TAG;
60 buf[1] = BODY_LEN;
61 buf[HEADER_LEN..HEADER_LEN + 2].copy_from_slice(&self.es_id.to_be_bytes());
62 Ok(len)
63 }
64}
65impl<'a> crate::traits::DescriptorDef<'a> for SlDescriptor {
66 const TAG: u8 = TAG;
67 const NAME: &'static str = "SL";
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn parse_extracts_es_id() {
76 let d = SlDescriptor::parse(&[TAG, 2, 0x12, 0x34]).unwrap();
77 assert_eq!(d.es_id, 0x1234);
78 }
79
80 #[test]
81 fn parse_rejects_wrong_tag() {
82 let err = SlDescriptor::parse(&[0x02, 2, 0, 0]).unwrap_err();
83 assert!(matches!(err, Error::InvalidDescriptor { tag: 0x02, .. }));
84 }
85
86 #[test]
87 fn parse_rejects_wrong_length() {
88 let err = SlDescriptor::parse(&[TAG, 3, 0, 0, 0]).unwrap_err();
89 assert!(matches!(err, Error::InvalidDescriptor { .. }));
90 }
91
92 #[test]
93 fn parse_rejects_short_buffer() {
94 let err = SlDescriptor::parse(&[TAG]).unwrap_err();
95 assert!(matches!(err, Error::BufferTooShort { .. }));
96 }
97
98 #[test]
99 fn serialize_round_trip() {
100 let d = SlDescriptor { es_id: 0xBEEF };
101 let mut buf = vec![0u8; d.serialized_len()];
102 d.serialize_into(&mut buf).unwrap();
103 assert_eq!(SlDescriptor::parse(&buf).unwrap(), d);
104 }
105}