Skip to main content

dvb_si/descriptors/
default_authority.rs

1//! Default Authority Descriptor — ETSI TS 102 323 §12.2.1 (tag 0x73).
2//!
3//! Carried inside NIT, BAT, SDT, EIT to provide the default TV-Anytime
4//! authority prefix used when resolving relative CRIDs.
5
6use super::descriptor_body;
7use crate::error::{Error, Result};
8use crate::text::DvbText;
9use dvb_common::{Parse, Serialize};
10
11/// Descriptor tag for default_authority_descriptor.
12pub const TAG: u8 = 0x73;
13const HEADER_LEN: usize = 2;
14
15/// Default Authority Descriptor.
16#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
18#[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
19pub struct DefaultAuthorityDescriptor<'a> {
20    /// Default authority text (e.g. "bbc.co.uk").
21    pub default_authority: DvbText<'a>,
22}
23
24impl<'a> Parse<'a> for DefaultAuthorityDescriptor<'a> {
25    type Error = crate::error::Error;
26    fn parse(bytes: &'a [u8]) -> Result<Self> {
27        let body = descriptor_body(
28            bytes,
29            TAG,
30            "DefaultAuthorityDescriptor",
31            "unexpected tag for default authority descriptor",
32        )?;
33        Ok(Self {
34            default_authority: DvbText::new(body),
35        })
36    }
37}
38
39impl Serialize for DefaultAuthorityDescriptor<'_> {
40    type Error = crate::error::Error;
41    fn serialized_len(&self) -> usize {
42        HEADER_LEN + self.default_authority.raw().len()
43    }
44
45    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
46        let len = self.serialized_len();
47        if buf.len() < len {
48            return Err(Error::OutputBufferTooSmall {
49                need: len,
50                have: buf.len(),
51            });
52        }
53        buf[0] = TAG;
54        buf[1] = self.default_authority.raw().len() as u8;
55        buf[HEADER_LEN..len].copy_from_slice(self.default_authority.raw());
56        Ok(len)
57    }
58}
59impl<'a> crate::traits::DescriptorDef<'a> for DefaultAuthorityDescriptor<'a> {
60    const TAG: u8 = TAG;
61    const NAME: &'static str = "DEFAULT_AUTHORITY";
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn parse_extracts_authority_text() {
70        let bytes = [TAG, 9, b'b', b'b', b'c', b'.', b'c', b'o', b'.', b'u', b'k'];
71        let d = DefaultAuthorityDescriptor::parse(&bytes).unwrap();
72        assert_eq!(d.default_authority.raw(), b"bbc.co.uk");
73        assert_eq!(d.default_authority.decode(), "bbc.co.uk");
74    }
75
76    #[test]
77    fn parse_rejects_wrong_tag() {
78        assert!(matches!(
79            DefaultAuthorityDescriptor::parse(&[0x7A, 1, 0]).unwrap_err(),
80            Error::InvalidDescriptor { tag: 0x7A, .. }
81        ));
82    }
83
84    #[test]
85    fn parse_rejects_short_header() {
86        assert!(matches!(
87            DefaultAuthorityDescriptor::parse(&[TAG]).unwrap_err(),
88            Error::BufferTooShort { .. }
89        ));
90    }
91
92    #[test]
93    fn parse_rejects_length_overrunning_buffer() {
94        let bytes = [TAG, 5, 1, 2, 3];
95        assert!(matches!(
96            DefaultAuthorityDescriptor::parse(&bytes).unwrap_err(),
97            Error::BufferTooShort { .. }
98        ));
99    }
100
101    #[test]
102    fn empty_authority_is_valid() {
103        let bytes = [TAG, 0];
104        let d = DefaultAuthorityDescriptor::parse(&bytes).unwrap();
105        assert!(d.default_authority.raw().is_empty());
106    }
107
108    #[test]
109    fn serialize_round_trip() {
110        let d = DefaultAuthorityDescriptor {
111            default_authority: DvbText::new(b"example.com"),
112        };
113        let mut buf = vec![0u8; d.serialized_len()];
114        d.serialize_into(&mut buf).unwrap();
115        assert_eq!(DefaultAuthorityDescriptor::parse(&buf).unwrap(), d);
116    }
117
118    #[test]
119    fn serialize_rejects_too_small_buffer() {
120        let d = DefaultAuthorityDescriptor {
121            default_authority: DvbText::new(b"test"),
122        };
123        let mut buf = vec![0u8; 1];
124        assert!(matches!(
125            d.serialize_into(&mut buf).unwrap_err(),
126            Error::OutputBufferTooSmall { .. }
127        ));
128    }
129}