zero_mysql/protocol/
packet.rs1use crate::error::{Error, Result, eyre};
2use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
3
4#[repr(C, packed)]
5#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, IntoBytes)]
6pub struct PacketHeader {
7 pub length: [u8; 3],
8 pub sequence_id: u8,
9}
10
11impl PacketHeader {
12 pub fn encode(length: usize, sequence_id: u8) -> Self {
13 let len = u32::to_le_bytes(length as u32);
14 Self {
15 length: [len[0], len[1], len[2]],
16 sequence_id,
17 }
18 }
19
20 pub fn encode_in_place(&mut self, length: usize, sequence_id: u8) {
21 let len = u32::to_le_bytes(length as u32);
22 self.length = [len[0], len[1], len[2]];
23 self.sequence_id = sequence_id;
24 }
25
26 pub fn length(&self) -> usize {
27 u32::from_le_bytes([self.length[0], self.length[1], self.length[2], 0]) as usize
28 }
29
30 pub fn from_bytes(data: &[u8]) -> Result<&Self> {
31 if data.len() < 4 {
32 return Err(Error::LibraryBug(eyre!(
33 "packet header too short: {} < 4",
34 data.len()
35 )));
36 }
37 Ok(Self::ref_from_bytes(&data[..4])?)
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn packet_header_has_alignment_of_1() {
47 assert_eq!(std::mem::align_of::<PacketHeader>(), 1);
48 }
49}