stabilizer_stream/de/
frame.rs

1use super::data::{self, Payload};
2use super::{Error, Format};
3
4use std::convert::TryFrom;
5
6// The magic word at the start of each stream frame.
7const MAGIC_WORD: [u8; 2] = [0x7b, 0x05];
8
9// The size of the frame header in bytes.
10const HEADER_SIZE: usize = 8;
11
12#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
13pub struct Header {
14    // The format code associated with the stream binary data.
15    pub format: Format,
16
17    // The number of batches in the payload.
18    pub batches: u8,
19
20    // The sequence number of the first batch in the binary data. The sequence number increments
21    // monotonically for each batch. All batches the binary data are sequential.
22    pub seq: u32,
23}
24
25impl Header {
26    /// Parse the header of a stream frame.
27    fn parse(header: &[u8; HEADER_SIZE]) -> Result<Self, Error> {
28        if header[..2] != MAGIC_WORD {
29            return Err(Error::InvalidHeader);
30        }
31        let format = Format::try_from(header[2]).or(Err(Error::UnknownFormat))?;
32        let batches = header[3];
33        let seq = u32::from_le_bytes(header[4..8].try_into().unwrap());
34        Ok(Self {
35            format,
36            batches,
37            seq,
38        })
39    }
40}
41
42/// A single stream frame contains multiple batches of data.
43// #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
44pub struct Frame {
45    pub header: Header,
46    pub data: Box<dyn Payload + Send>,
47}
48
49impl Frame {
50    /// Parse a stream frame from a single UDP packet.
51    pub fn from_bytes(input: &[u8]) -> Result<Self, Error> {
52        let header = Header::parse(&input[..HEADER_SIZE].try_into().unwrap())?;
53        let data = &input[HEADER_SIZE..];
54        let data: Box<dyn Payload + Send> = match header.format {
55            Format::AdcDac => Box::new(data::AdcDac::new(header.batches as _, data)?),
56            Format::Fls => Box::new(data::Fls::new(header.batches as _, data)?),
57        };
58        Ok(Self { header, data })
59    }
60}