dvb_si/descriptors/
time_shifted_event.rs1use crate::error::{Error, Result};
8use crate::traits::Descriptor;
9use dvb_common::{Parse, Serialize};
10
11pub const TAG: u8 = 0x4F;
13const HEADER_LEN: usize = 2;
14const BODY_LEN: usize = 4;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize))]
19pub struct TimeShiftedEventDescriptor {
20 pub reference_service_id: u16,
22 pub reference_event_id: u16,
24}
25
26impl<'a> Parse<'a> for TimeShiftedEventDescriptor {
27 type Error = crate::error::Error;
28 fn parse(bytes: &'a [u8]) -> Result<Self> {
29 if bytes.len() < HEADER_LEN {
30 return Err(Error::BufferTooShort {
31 need: HEADER_LEN,
32 have: bytes.len(),
33 what: "TimeShiftedEventDescriptor header",
34 });
35 }
36 if bytes[0] != TAG {
37 return Err(Error::InvalidDescriptor {
38 tag: bytes[0],
39 reason: "unexpected tag for time_shifted_event_descriptor",
40 });
41 }
42 let length = bytes[1] as usize;
43 if length != BODY_LEN {
44 return Err(Error::InvalidDescriptor {
45 tag: TAG,
46 reason: "time_shifted_event_descriptor length must be 4",
47 });
48 }
49 let end = HEADER_LEN + BODY_LEN;
50 if bytes.len() < end {
51 return Err(Error::BufferTooShort {
52 need: end,
53 have: bytes.len(),
54 what: "TimeShiftedEventDescriptor body",
55 });
56 }
57 Ok(Self {
58 reference_service_id: u16::from_be_bytes([bytes[2], bytes[3]]),
59 reference_event_id: u16::from_be_bytes([bytes[4], bytes[5]]),
60 })
61 }
62}
63
64impl Serialize for TimeShiftedEventDescriptor {
65 type Error = crate::error::Error;
66 fn serialized_len(&self) -> usize {
67 HEADER_LEN + BODY_LEN
68 }
69
70 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
71 let len = self.serialized_len();
72 if buf.len() < len {
73 return Err(Error::OutputBufferTooSmall {
74 need: len,
75 have: buf.len(),
76 });
77 }
78 buf[0] = TAG;
79 buf[1] = BODY_LEN as u8;
80 buf[2..4].copy_from_slice(&self.reference_service_id.to_be_bytes());
81 buf[4..6].copy_from_slice(&self.reference_event_id.to_be_bytes());
82 Ok(len)
83 }
84}
85
86impl<'a> Descriptor<'a> for TimeShiftedEventDescriptor {
87 const TAG: u8 = TAG;
88 fn descriptor_length(&self) -> u8 {
89 BODY_LEN as u8
90 }
91}
92
93impl<'a> crate::traits::DescriptorDef<'a> for TimeShiftedEventDescriptor {
94 const TAG: u8 = TAG;
95 const NAME: &'static str = "TIME_SHIFTED_EVENT";
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn parse_reference_ids() {
104 let bytes = [TAG, 4, 0x12, 0x34, 0x56, 0x78];
105 let d = TimeShiftedEventDescriptor::parse(&bytes).unwrap();
106 assert_eq!(d.reference_service_id, 0x1234);
107 assert_eq!(d.reference_event_id, 0x5678);
108 }
109
110 #[test]
111 fn parse_rejects_wrong_tag() {
112 assert!(matches!(
113 TimeShiftedEventDescriptor::parse(&[0x50, 4, 0, 0, 0, 0]).unwrap_err(),
114 Error::InvalidDescriptor { tag: 0x50, .. }
115 ));
116 }
117
118 #[test]
119 fn parse_rejects_short_buffer() {
120 let bytes = [TAG, 4, 0x12, 0x34, 0x56];
122 assert!(matches!(
123 TimeShiftedEventDescriptor::parse(&bytes).unwrap_err(),
124 Error::BufferTooShort { .. }
125 ));
126 }
127
128 #[test]
129 fn parse_rejects_wrong_length() {
130 let bytes = [TAG, 5, 0x12, 0x34, 0x56, 0x78, 0x00];
131 assert!(matches!(
132 TimeShiftedEventDescriptor::parse(&bytes).unwrap_err(),
133 Error::InvalidDescriptor { tag: TAG, .. }
134 ));
135 }
136
137 #[test]
138 fn serialize_round_trip() {
139 let d = TimeShiftedEventDescriptor {
140 reference_service_id: 0xABCD,
141 reference_event_id: 0x0102,
142 };
143 let mut buf = vec![0u8; d.serialized_len()];
144 d.serialize_into(&mut buf).unwrap();
145 assert_eq!(TimeShiftedEventDescriptor::parse(&buf).unwrap(), d);
146 }
147
148 #[test]
149 fn serialize_rejects_small_buffer() {
150 let d = TimeShiftedEventDescriptor {
151 reference_service_id: 1,
152 reference_event_id: 2,
153 };
154 let mut tiny = [0u8; 5];
155 assert!(matches!(
156 d.serialize_into(&mut tiny).unwrap_err(),
157 Error::OutputBufferTooSmall { .. }
158 ));
159 }
160
161 #[cfg(feature = "serde")]
162 #[test]
163 fn serde_round_trip() {
164 let d = TimeShiftedEventDescriptor {
165 reference_service_id: 0x1234,
166 reference_event_id: 0x5678,
167 };
168 let json = serde_json::to_string(&d).unwrap();
169 let _v: serde_json::Value = serde_json::from_str(&json).unwrap();
171 }
172}