dvb_si/descriptors/
time_shifted_event.rs1use super::descriptor_body;
8use crate::error::{Error, Result};
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 let body = descriptor_body(
30 bytes,
31 TAG,
32 "TimeShiftedEventDescriptor",
33 "unexpected tag for time_shifted_event_descriptor",
34 )?;
35 if body.len() != BODY_LEN {
36 return Err(Error::InvalidDescriptor {
37 tag: TAG,
38 reason: "time_shifted_event_descriptor length must be 4",
39 });
40 }
41 Ok(Self {
42 reference_service_id: u16::from_be_bytes([body[0], body[1]]),
43 reference_event_id: u16::from_be_bytes([body[2], body[3]]),
44 })
45 }
46}
47
48impl Serialize for TimeShiftedEventDescriptor {
49 type Error = crate::error::Error;
50 fn serialized_len(&self) -> usize {
51 HEADER_LEN + BODY_LEN
52 }
53
54 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
55 let len = self.serialized_len();
56 if buf.len() < len {
57 return Err(Error::OutputBufferTooSmall {
58 need: len,
59 have: buf.len(),
60 });
61 }
62 buf[0] = TAG;
63 buf[1] = BODY_LEN as u8;
64 buf[2..4].copy_from_slice(&self.reference_service_id.to_be_bytes());
65 buf[4..6].copy_from_slice(&self.reference_event_id.to_be_bytes());
66 Ok(len)
67 }
68}
69impl<'a> crate::traits::DescriptorDef<'a> for TimeShiftedEventDescriptor {
70 const TAG: u8 = TAG;
71 const NAME: &'static str = "TIME_SHIFTED_EVENT";
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn parse_reference_ids() {
80 let bytes = [TAG, 4, 0x12, 0x34, 0x56, 0x78];
81 let d = TimeShiftedEventDescriptor::parse(&bytes).unwrap();
82 assert_eq!(d.reference_service_id, 0x1234);
83 assert_eq!(d.reference_event_id, 0x5678);
84 }
85
86 #[test]
87 fn parse_rejects_wrong_tag() {
88 assert!(matches!(
89 TimeShiftedEventDescriptor::parse(&[0x50, 4, 0, 0, 0, 0]).unwrap_err(),
90 Error::InvalidDescriptor { tag: 0x50, .. }
91 ));
92 }
93
94 #[test]
95 fn parse_rejects_short_buffer() {
96 let bytes = [TAG, 4, 0x12, 0x34, 0x56];
98 assert!(matches!(
99 TimeShiftedEventDescriptor::parse(&bytes).unwrap_err(),
100 Error::BufferTooShort { .. }
101 ));
102 }
103
104 #[test]
105 fn parse_rejects_wrong_length() {
106 let bytes = [TAG, 5, 0x12, 0x34, 0x56, 0x78, 0x00];
107 assert!(matches!(
108 TimeShiftedEventDescriptor::parse(&bytes).unwrap_err(),
109 Error::InvalidDescriptor { tag: TAG, .. }
110 ));
111 }
112
113 #[test]
114 fn serialize_round_trip() {
115 let d = TimeShiftedEventDescriptor {
116 reference_service_id: 0xABCD,
117 reference_event_id: 0x0102,
118 };
119 let mut buf = vec![0u8; d.serialized_len()];
120 d.serialize_into(&mut buf).unwrap();
121 assert_eq!(TimeShiftedEventDescriptor::parse(&buf).unwrap(), d);
122 }
123
124 #[test]
125 fn serialize_rejects_small_buffer() {
126 let d = TimeShiftedEventDescriptor {
127 reference_service_id: 1,
128 reference_event_id: 2,
129 };
130 let mut tiny = [0u8; 5];
131 assert!(matches!(
132 d.serialize_into(&mut tiny).unwrap_err(),
133 Error::OutputBufferTooSmall { .. }
134 ));
135 }
136
137 #[cfg(feature = "serde")]
138 #[test]
139 fn serde_round_trip() {
140 let d = TimeShiftedEventDescriptor {
141 reference_service_id: 0x1234,
142 reference_event_id: 0x5678,
143 };
144 let json = serde_json::to_string(&d).unwrap();
145 let _v: serde_json::Value = serde_json::from_str(&json).unwrap();
147 }
148}