1pub mod packet_type;
4pub use packet_type::*;
5
6pub mod pixel_config;
7pub use pixel_config::{PixelConfig, PixelFormat};
8
9pub mod id;
10pub use id::ID;
11
12pub mod message;
13
14pub mod timecode;
15use timecode::TimeCode;
16
17#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Default)]
18pub struct Header {
19 pub packet_type: PacketType,
20 pub sequence_number: u8,
21 pub pixel_config: PixelConfig,
22 pub id: ID,
23 pub offset: u32,
24 pub length: u16,
25 pub time_code: TimeCode, }
27
28impl Into<[u8; 10]> for Header {
29 fn into(self) -> [u8; 10] {
30 let mut buffer: [u8; 10] = [0u8; 10];
32
33 let packet_type_byte: u8 = self.packet_type.into();
36 buffer[0] = packet_type_byte;
37
38 buffer[1] = self.sequence_number;
40
41 buffer[2] = self.pixel_config.into();
43
44 buffer[3] = self.id.into();
46
47 let offset_bytes = self.offset.to_be_bytes();
49 buffer[4..8].copy_from_slice(&offset_bytes);
50
51 let length_bytes = self.length.to_be_bytes();
53 buffer[8..10].copy_from_slice(&length_bytes);
54
55 buffer
57 }
58}
59impl Into<[u8; 14]> for Header {
60 fn into(self) -> [u8; 14] {
61 let mut buffer = [0u8; 14];
63
64 let packet_type_byte: u8 = self.packet_type.into();
67 buffer[0] = packet_type_byte;
68
69 buffer[1] = self.sequence_number;
71
72 buffer[2] = self.pixel_config.into();
74
75 buffer[3] = self.id.into();
77
78 let offset_bytes: [u8; 4] = self.offset.to_be_bytes();
80 buffer[4..8].copy_from_slice(&offset_bytes);
81
82 let length_bytes: [u8; 2] = self.length.to_be_bytes();
84 buffer[8..10].copy_from_slice(&length_bytes);
85
86 let time_code: [u8; 4] = self.time_code.to_bytes();
87 buffer[10..14].copy_from_slice(&time_code);
88
89 buffer
91 }
92}
93
94impl<'a> From<&'a [u8]> for Header {
95 fn from(bytes: &'a [u8]) -> Self {
96 let packet_type = PacketType::from(bytes[0]);
98
99 let sequence_number = bytes[1];
101
102 let pixel_config = PixelConfig::from(bytes[2]);
104
105 let id = ID::from(bytes[3]);
107
108 let offset = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
110
111 let length = u16::from_be_bytes([bytes[8], bytes[9]]);
113
114 if packet_type.timecode && bytes.len() >= 14 {
115 let time_code = TimeCode::from_4_bytes([bytes[10], bytes[11], bytes[12], bytes[13]]);
116
117 Header {
118 packet_type,
119 sequence_number,
120 pixel_config,
121 id,
122 offset,
123 length,
124 time_code,
125 }
126 } else {
127 Header {
128 packet_type,
129 sequence_number,
130 pixel_config,
131 id,
132 offset,
133 length,
134 time_code: TimeCode(None),
135 }
136 }
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143
144 #[test]
145 fn test_parsing() {
146 {
148 let data: [u8; 10] = [65, 6, 10, 1, 0, 0, 0, 0, 0, 3];
149 let header = Header::from(&data[..]);
150
151 assert_eq!(
152 header.packet_type,
153 PacketType {
154 version: 1,
155 timecode: false,
156 storage: false,
157 reply: false,
158 query: false,
159 push: true
160 }
161 );
162 assert_eq!(header.sequence_number, 6);
163 assert_eq!(header.length, 3);
164 assert_eq!(header.offset, 0);
165 }
166
167 {
169 let data: [u8; 10] = [255, 12, 13, 1, 0, 0, 0x99, 0xd5, 0x01, 0x19];
170 let header = Header::from(&data[..]);
171
172 assert_eq!(
173 header.packet_type,
174 PacketType {
175 version: 3,
176 timecode: true,
177 storage: true,
178 reply: true,
179 query: true,
180 push: true
181 }
182 );
183
184 assert_eq!(header.sequence_number, 12);
185 assert_eq!(
186 header.pixel_config,
187 PixelConfig {
188 data_type: pixel_config::DataType::RGB,
189 data_size: PixelFormat::Pixel24Bits,
190 customer_defined: false
191 }
192 );
193 assert_eq!(header.length, 281);
194 assert_eq!(header.offset, 39381);
195 }
196 }
197}