zero-mysql 0.6.0

A high-performance MySQL client
Documentation
use crate::error::{Error, Result, eyre};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};

#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, IntoBytes)]
pub struct PacketHeader {
    pub length: [u8; 3],
    pub sequence_id: u8,
}

impl PacketHeader {
    pub fn encode(length: usize, sequence_id: u8) -> Self {
        let len = u32::to_le_bytes(length as u32);
        Self {
            length: [len[0], len[1], len[2]],
            sequence_id,
        }
    }

    pub fn encode_in_place(&mut self, length: usize, sequence_id: u8) {
        let len = u32::to_le_bytes(length as u32);
        self.length = [len[0], len[1], len[2]];
        self.sequence_id = sequence_id;
    }

    pub fn length(&self) -> usize {
        u32::from_le_bytes([self.length[0], self.length[1], self.length[2], 0]) as usize
    }

    pub fn from_bytes(data: &[u8]) -> Result<&Self> {
        if data.len() < 4 {
            return Err(Error::LibraryBug(eyre!(
                "packet header too short: {} < 4",
                data.len()
            )));
        }
        Ok(Self::ref_from_bytes(&data[..4])?)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn packet_header_has_alignment_of_1() {
        assert_eq!(std::mem::align_of::<PacketHeader>(), 1);
    }
}