dvb_si/descriptors/
related_content.rs1use super::descriptor_body;
11use crate::error::{Error, Result};
12use dvb_common::{Parse, Serialize};
13
14pub const TAG: u8 = 0x74;
16const HEADER_LEN: usize = 2;
17
18#[derive(Debug, Clone, PartialEq, Eq, Default)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize))]
23pub struct RelatedContentDescriptor;
24
25impl<'a> Parse<'a> for RelatedContentDescriptor {
26 type Error = crate::error::Error;
27 fn parse(bytes: &'a [u8]) -> Result<Self> {
28 let _body = descriptor_body(
29 bytes,
30 TAG,
31 "RelatedContentDescriptor",
32 "unexpected tag for related_content_descriptor",
33 )?;
34 Ok(Self)
37 }
38}
39
40impl Serialize for RelatedContentDescriptor {
41 type Error = crate::error::Error;
42 fn serialized_len(&self) -> usize {
43 HEADER_LEN
44 }
45
46 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
47 let len = self.serialized_len();
48 if buf.len() < len {
49 return Err(Error::OutputBufferTooSmall {
50 need: len,
51 have: buf.len(),
52 });
53 }
54 buf[0] = TAG;
55 buf[1] = 0;
56 Ok(len)
57 }
58}
59impl<'a> crate::traits::DescriptorDef<'a> for RelatedContentDescriptor {
60 const TAG: u8 = TAG;
61 const NAME: &'static str = "RELATED_CONTENT";
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn parse_empty_marker() {
70 let bytes = [TAG, 0];
71 let d = RelatedContentDescriptor::parse(&bytes).unwrap();
72 assert_eq!(d, RelatedContentDescriptor);
73 }
74
75 #[test]
76 fn parse_rejects_wrong_tag() {
77 assert!(matches!(
78 RelatedContentDescriptor::parse(&[0x73, 0]).unwrap_err(),
79 Error::InvalidDescriptor { tag: 0x73, .. }
80 ));
81 }
82
83 #[test]
84 fn parse_rejects_short_header() {
85 assert!(matches!(
86 RelatedContentDescriptor::parse(&[TAG]).unwrap_err(),
87 Error::BufferTooShort { .. }
88 ));
89 }
90
91 #[test]
92 fn parse_rejects_length_overrunning_buffer() {
93 let bytes = [TAG, 3, 1, 2];
94 assert!(matches!(
95 RelatedContentDescriptor::parse(&bytes).unwrap_err(),
96 Error::BufferTooShort { .. }
97 ));
98 }
99
100 #[test]
101 fn serialize_round_trip() {
102 let d = RelatedContentDescriptor;
103 let mut buf = vec![0u8; d.serialized_len()];
104 let n = d.serialize_into(&mut buf).unwrap();
105 assert_eq!(n, 2);
106 assert_eq!(buf, vec![TAG, 0]);
107 assert_eq!(RelatedContentDescriptor::parse(&buf).unwrap(), d);
108 }
109
110 #[test]
111 fn serialize_rejects_too_small_buffer() {
112 let d = RelatedContentDescriptor;
113 let mut buf = vec![0u8; 1];
114 assert!(matches!(
115 d.serialize_into(&mut buf).unwrap_err(),
116 Error::OutputBufferTooSmall { .. }
117 ));
118 }
119
120 #[cfg(feature = "serde")]
121 #[test]
122 fn serde_round_trip() {
123 let d = RelatedContentDescriptor;
124 let j = serde_json::to_string(&d).unwrap();
125 let _v: serde_json::Value = serde_json::from_str(&j).unwrap();
127 }
128}