pub mod packet_type;
pub use packet_type::*;
pub mod pixel_config;
pub use pixel_config::{PixelConfig, PixelFormat};
pub mod id;
pub use id::ID;
use crate::protocol::timecode::TimeCode;
pub mod message;
pub mod timecode;
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct Header {
pub packet_type: PacketType,
pub sequence_number: u8,
pub pixel_config: PixelConfig,
pub id: ID,
pub offset: u32,
pub length: u16,
pub time_code: TimeCode, }
impl Default for Header {
fn default() -> Self {
Self {
packet_type: Default::default(),
sequence_number: Default::default(),
pixel_config: Default::default(),
id: Default::default(),
offset: Default::default(),
length: Default::default(),
time_code: Default::default(),
}
}
}
impl Into<[u8; 10]> for Header {
fn into(self) -> [u8; 10] {
let mut buffer: [u8; 10] = [0u8; 10];
let packet_type_byte: u8 = self.packet_type.into();
buffer[0] = packet_type_byte;
buffer[1] = self.sequence_number;
buffer[2] = self.pixel_config.into();
buffer[3] = self.id.into();
let offset_bytes = self.offset.to_be_bytes();
buffer[4..8].copy_from_slice(&offset_bytes);
let length_bytes = self.length.to_be_bytes();
buffer[8..10].copy_from_slice(&length_bytes);
buffer
}
}
impl Into<[u8; 14]> for Header {
fn into(self) -> [u8; 14] {
let mut buffer = [0u8; 14];
let packet_type_byte: u8 = self.packet_type.into();
buffer[0] = packet_type_byte;
buffer[1] = self.sequence_number;
buffer[2] = self.pixel_config.into();
buffer[3] = self.id.into();
let offset_bytes: [u8; 4] = self.offset.to_be_bytes();
buffer[4..8].copy_from_slice(&offset_bytes);
let length_bytes: [u8; 2] = self.length.to_be_bytes();
buffer[8..10].copy_from_slice(&length_bytes);
let time_code: [u8; 4] = self.time_code.to_bytes();
buffer[10..14].copy_from_slice(&time_code);
buffer
}
}
impl<'a> From<&'a [u8]> for Header {
fn from(bytes: &'a [u8]) -> Self {
let packet_type = PacketType::from(bytes[0]);
let sequence_number = bytes[1];
let pixel_config = PixelConfig::from(bytes[2]);
let id = ID::from(bytes[3]);
let offset = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
let length = u16::from_be_bytes([bytes[8], bytes[9]]);
return if packet_type.timecode && bytes.len() >= 14 {
let time_code = TimeCode::from_4_bytes([bytes[10], bytes[11], bytes[12], bytes[13]]);
Header {
packet_type,
sequence_number,
pixel_config,
id,
offset,
length,
time_code
}
} else {
Header {
packet_type,
sequence_number,
pixel_config,
id,
offset,
length,
time_code: TimeCode(None)
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parsing() {
{
let data: [u8; 10] = [65, 6, 10, 1, 0, 0, 0, 0, 0, 3];
let header = Header::from(&data[..]);
assert_eq!(
header.packet_type,
PacketType {
version: 1,
timecode: false,
storage: false,
reply: false,
query: false,
push: true
}
);
assert_eq!(header.sequence_number, 6);
assert_eq!(header.length, 3);
assert_eq!(header.offset, 0);
}
{
let data: [u8; 10] = [255, 12, 13, 1, 0, 0, 0x99, 0xd5, 0x01, 0x19];
let header = Header::from(&data[..]);
assert_eq!(
header.packet_type,
PacketType {
version: 3,
timecode: true,
storage: true,
reply: true,
query: true,
push: true
}
);
assert_eq!(header.sequence_number, 12);
assert_eq!(
header.pixel_config,
PixelConfig {
data_type: pixel_config::DataType::RGB,
data_size: PixelFormat::Pixel24Bits,
customer_defined: false
}
);
assert_eq!(header.length, 281);
assert_eq!(header.offset, 39381);
}
}
}