Skip to main content

dvb_si/collect/
nit.rs

1use crate::descriptors::DescriptorRegistry;
2use crate::tables::nit;
3
4use super::{CompleteSectionSet, ParsedDescriptorLoop};
5
6/// Transport-stream entry in a complete NIT.
7#[derive(Debug)]
8#[non_exhaustive]
9pub struct CompleteNitTransportStream<'a> {
10    /// transport_stream_id of the described TS.
11    pub transport_stream_id: u16,
12    /// original_network_id of the described TS.
13    pub original_network_id: u16,
14    /// Typed descriptor loop for this transport stream.
15    pub descriptors: ParsedDescriptorLoop<'a>,
16}
17
18/// Complete logical Network Information Table.
19#[derive(Debug)]
20#[non_exhaustive]
21pub struct CompleteNit<'a> {
22    /// Variant discriminator.
23    pub kind: nit::NitKind,
24    /// Network identifier.
25    pub network_id: u16,
26    /// 5-bit version_number.
27    pub version_number: u8,
28    /// current_next_indicator bit.
29    pub current_next_indicator: bool,
30    /// Network-wide descriptors from section 0.
31    pub network_descriptors: ParsedDescriptorLoop<'a>,
32    /// Transport-stream loop entries from all sections in wire order.
33    pub transport_streams: Vec<CompleteNitTransportStream<'a>>,
34}
35
36impl<'a> CompleteNit<'a> {
37    pub(crate) fn parse(
38        set: &'a CompleteSectionSet,
39        registry: Option<&'a DescriptorRegistry>,
40    ) -> crate::Result<Self> {
41        let sections: Vec<nit::NitSection<'a>> = set.parse_sections()?;
42        let first = sections.first().ok_or(crate::Error::BufferTooShort {
43            need: 1,
44            have: 0,
45            what: "CompleteNit sections",
46        })?;
47        let mut transport_streams = Vec::new();
48        for section in &sections {
49            transport_streams.extend(section.transport_streams.iter().map(|ts| {
50                CompleteNitTransportStream {
51                    transport_stream_id: ts.transport_stream_id,
52                    original_network_id: ts.original_network_id,
53                    descriptors: ParsedDescriptorLoop::parse(ts.descriptors, registry),
54                }
55            }));
56        }
57        Ok(Self {
58            kind: first.kind,
59            network_id: first.network_id,
60            version_number: first.version_number,
61            current_next_indicator: first.current_next_indicator,
62            // The network descriptor loop is carried in section 0; completed
63            // sets are stored in section-number order, so `first` is
64            // authoritative for table-wide descriptors.
65            network_descriptors: ParsedDescriptorLoop::parse(first.network_descriptors, registry),
66            transport_streams,
67        })
68    }
69}