scatter_net/scatter_net/packet/methods/
from_net_buffer.rs

1use crate::Packet;
2
3impl Packet {
4    /// Reads the first packet from a network buffer.
5    pub fn from_net_buffer(
6        bytes: &[u8],
7    ) -> Result<Option<(usize, Self)>, PacketFromNetBufferError> {
8        if bytes.len() < 8 {
9            return Ok(None);
10        }
11
12        let length = usize::try_from(u32::from_be_bytes(bytes[0..4].try_into()?))?;
13
14        if bytes.len() < length {
15            return Ok(None);
16        }
17
18        let packet = Self::from_bytes(&bytes[..length])?;
19
20        Ok(Some((length, packet)))
21    }
22}
23
24#[derive(thiserror::Error, Debug)]
25pub enum PacketFromNetBufferError {
26    #[error(transparent)]
27    FromBytes(#[from] anyhow::Error),
28    #[error(transparent)]
29    Int(#[from] std::num::TryFromIntError),
30    #[error(transparent)]
31    Slice(#[from] std::array::TryFromSliceError),
32}
33
34#[cfg(test)]
35mod tests {
36    use anyhow::{bail, Result};
37    use ps_buffer::Buffer;
38
39    use crate::Packet;
40
41    #[test]
42    fn roundtrip() -> Result<()> {
43        let packet = Packet::Pong;
44        let serialized = packet.to_bytes()?;
45
46        let mut buffer = Buffer::alloc_uninit(200_000)?;
47
48        buffer[0..serialized.len()].copy_from_slice(&serialized);
49
50        if let Some((size, dpacket)) = Packet::from_net_buffer(&buffer)? {
51            assert_eq!(packet, dpacket, "Packets should match");
52            assert_eq!(size, serialized.len(), "Packet lengths should match");
53        } else {
54            bail!("Packet deserialization failed");
55        }
56
57        Ok(())
58    }
59}