1use crate::buffer::{ReadBuffer, WriteBuffer};
9
10#[repr(C, packed)]
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
27pub struct MessageHeader {
28 pub block_length: u16,
30 pub template_id: u16,
32 pub schema_id: u16,
34 pub version: u16,
36}
37
38impl MessageHeader {
39 pub const ENCODED_LENGTH: usize = 8;
41
42 #[must_use]
50 pub const fn new(block_length: u16, template_id: u16, schema_id: u16, version: u16) -> Self {
51 Self {
52 block_length,
53 template_id,
54 schema_id,
55 version,
56 }
57 }
58
59 #[inline(always)]
68 #[must_use]
69 pub fn wrap<B: ReadBuffer + ?Sized>(buffer: &B, offset: usize) -> Self {
70 Self {
71 block_length: buffer.get_u16_le(offset),
72 template_id: buffer.get_u16_le(offset + 2),
73 schema_id: buffer.get_u16_le(offset + 4),
74 version: buffer.get_u16_le(offset + 6),
75 }
76 }
77
78 #[inline(always)]
84 pub fn encode<B: WriteBuffer + ?Sized>(&self, buffer: &mut B, offset: usize) {
85 buffer.put_u16_le(offset, self.block_length);
86 buffer.put_u16_le(offset + 2, self.template_id);
87 buffer.put_u16_le(offset + 4, self.schema_id);
88 buffer.put_u16_le(offset + 6, self.version);
89 }
90
91 #[must_use]
93 pub const fn message_size(&self) -> usize {
94 Self::ENCODED_LENGTH + self.block_length as usize
95 }
96}
97
98#[repr(C, packed)]
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
111pub struct GroupHeader {
112 pub block_length: u16,
114 pub num_in_group: u16,
116}
117
118impl GroupHeader {
119 pub const ENCODED_LENGTH: usize = 4;
121
122 #[must_use]
128 pub const fn new(block_length: u16, num_in_group: u16) -> Self {
129 Self {
130 block_length,
131 num_in_group,
132 }
133 }
134
135 #[inline(always)]
144 #[must_use]
145 pub fn wrap<B: ReadBuffer + ?Sized>(buffer: &B, offset: usize) -> Self {
146 Self {
147 block_length: buffer.get_u16_le(offset),
148 num_in_group: buffer.get_u16_le(offset + 2),
149 }
150 }
151
152 #[inline(always)]
158 pub fn encode<B: WriteBuffer + ?Sized>(&self, buffer: &mut B, offset: usize) {
159 buffer.put_u16_le(offset, self.block_length);
160 buffer.put_u16_le(offset + 2, self.num_in_group);
161 }
162
163 #[must_use]
165 pub const fn group_size(&self) -> usize {
166 Self::ENCODED_LENGTH + (self.block_length as usize * self.num_in_group as usize)
167 }
168
169 #[must_use]
171 pub const fn is_empty(&self) -> bool {
172 self.num_in_group == 0
173 }
174}
175
176#[repr(C, packed)]
188#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
189pub struct VarDataHeader {
190 pub length: u16,
192}
193
194impl VarDataHeader {
195 pub const ENCODED_LENGTH: usize = 2;
197
198 #[must_use]
203 pub const fn new(length: u16) -> Self {
204 Self { length }
205 }
206
207 #[inline(always)]
216 #[must_use]
217 pub fn wrap<B: ReadBuffer + ?Sized>(buffer: &B, offset: usize) -> Self {
218 Self {
219 length: buffer.get_u16_le(offset),
220 }
221 }
222
223 #[inline(always)]
229 pub fn encode<B: WriteBuffer + ?Sized>(&self, buffer: &mut B, offset: usize) {
230 buffer.put_u16_le(offset, self.length);
231 }
232
233 #[must_use]
235 pub const fn total_size(&self) -> usize {
236 Self::ENCODED_LENGTH + self.length as usize
237 }
238
239 #[must_use]
241 pub const fn is_empty(&self) -> bool {
242 self.length == 0
243 }
244}
245
246#[repr(C, packed)]
248#[derive(Debug, Clone, Copy, PartialEq, Eq)]
249pub struct VarDataHeader8 {
250 pub length: u8,
252}
253
254impl VarDataHeader8 {
255 pub const ENCODED_LENGTH: usize = 1;
257
258 #[must_use]
260 pub const fn new(length: u8) -> Self {
261 Self { length }
262 }
263
264 #[inline(always)]
266 #[must_use]
267 pub fn wrap<B: ReadBuffer + ?Sized>(buffer: &B, offset: usize) -> Self {
268 Self {
269 length: buffer.get_u8(offset),
270 }
271 }
272
273 #[inline(always)]
275 pub fn encode<B: WriteBuffer + ?Sized>(&self, buffer: &mut B, offset: usize) {
276 buffer.put_u8(offset, self.length);
277 }
278}
279
280#[repr(C, packed)]
282#[derive(Debug, Clone, Copy, PartialEq, Eq)]
283pub struct VarDataHeader32 {
284 pub length: u32,
286}
287
288impl VarDataHeader32 {
289 pub const ENCODED_LENGTH: usize = 4;
291
292 #[must_use]
294 pub const fn new(length: u32) -> Self {
295 Self { length }
296 }
297
298 #[inline(always)]
300 #[must_use]
301 pub fn wrap<B: ReadBuffer + ?Sized>(buffer: &B, offset: usize) -> Self {
302 Self {
303 length: buffer.get_u32_le(offset),
304 }
305 }
306
307 #[inline(always)]
309 pub fn encode<B: WriteBuffer + ?Sized>(&self, buffer: &mut B, offset: usize) {
310 buffer.put_u32_le(offset, self.length);
311 }
312}
313
314#[cfg(test)]
315mod tests {
316 use super::*;
317 use crate::buffer::AlignedBuffer;
318
319 #[test]
320 fn test_message_header_encode_decode() {
321 let mut buf: AlignedBuffer<16> = AlignedBuffer::new();
322 let header = MessageHeader::new(64, 1, 100, 1);
323
324 header.encode(&mut buf, 0);
325 let decoded = MessageHeader::wrap(&buf, 0);
326
327 assert_eq!(header, decoded);
328 assert_eq!({ decoded.block_length }, 64);
329 assert_eq!({ decoded.template_id }, 1);
330 assert_eq!({ decoded.schema_id }, 100);
331 assert_eq!({ decoded.version }, 1);
332 }
333
334 #[test]
335 fn test_message_header_size() {
336 assert_eq!(MessageHeader::ENCODED_LENGTH, 8);
337 let header = MessageHeader::new(64, 1, 100, 1);
338 assert_eq!(header.message_size(), 72);
339 }
340
341 #[test]
342 fn test_group_header_encode_decode() {
343 let mut buf: AlignedBuffer<16> = AlignedBuffer::new();
344 let header = GroupHeader::new(32, 5);
345
346 header.encode(&mut buf, 0);
347 let decoded = GroupHeader::wrap(&buf, 0);
348
349 assert_eq!(header, decoded);
350 assert_eq!({ decoded.block_length }, 32);
351 assert_eq!({ decoded.num_in_group }, 5);
352 }
353
354 #[test]
355 fn test_group_header_size() {
356 assert_eq!(GroupHeader::ENCODED_LENGTH, 4);
357 let header = GroupHeader::new(32, 5);
358 assert_eq!(header.group_size(), 4 + 32 * 5);
359 assert!(!header.is_empty());
360
361 let empty = GroupHeader::new(32, 0);
362 assert!(empty.is_empty());
363 }
364
365 #[test]
366 fn test_var_data_header_encode_decode() {
367 let mut buf: AlignedBuffer<16> = AlignedBuffer::new();
368 let header = VarDataHeader::new(256);
369
370 header.encode(&mut buf, 0);
371 let decoded = VarDataHeader::wrap(&buf, 0);
372
373 assert_eq!(header, decoded);
374 assert_eq!({ decoded.length }, 256);
375 assert_eq!(decoded.total_size(), 258);
376 }
377
378 #[test]
379 fn test_var_data_header8() {
380 let mut buf: AlignedBuffer<16> = AlignedBuffer::new();
381 let header = VarDataHeader8::new(100);
382
383 header.encode(&mut buf, 0);
384 let decoded = VarDataHeader8::wrap(&buf, 0);
385
386 assert_eq!(header, decoded);
387 assert_eq!(VarDataHeader8::ENCODED_LENGTH, 1);
388 }
389
390 #[test]
391 fn test_var_data_header32() {
392 let mut buf: AlignedBuffer<16> = AlignedBuffer::new();
393 let header = VarDataHeader32::new(1_000_000);
394
395 header.encode(&mut buf, 0);
396 let decoded = VarDataHeader32::wrap(&buf, 0);
397
398 assert_eq!(header, decoded);
399 assert_eq!(VarDataHeader32::ENCODED_LENGTH, 4);
400 }
401
402 #[test]
403 fn test_header_wire_format() {
404 let mut buf: AlignedBuffer<16> = AlignedBuffer::new();
405 let header = MessageHeader::new(0x0102, 0x0304, 0x0506, 0x0708);
406 header.encode(&mut buf, 0);
407
408 assert_eq!(buf.get_u8(0), 0x02); assert_eq!(buf.get_u8(1), 0x01); assert_eq!(buf.get_u8(2), 0x04); assert_eq!(buf.get_u8(3), 0x03); assert_eq!(buf.get_u8(4), 0x06); assert_eq!(buf.get_u8(5), 0x05); assert_eq!(buf.get_u8(6), 0x08); assert_eq!(buf.get_u8(7), 0x07); }
418}