Skip to main content

nnrp_runtime/
packet.rs

1use nnrp_core::{CommonHeader, NnrpError, COMMON_HEADER_LEN};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct RuntimePacket {
5    pub header: CommonHeader,
6    pub metadata: Vec<u8>,
7    pub body: Vec<u8>,
8}
9
10impl RuntimePacket {
11    pub fn new(
12        mut header: CommonHeader,
13        metadata: Vec<u8>,
14        body: Vec<u8>,
15    ) -> Result<Self, NnrpError> {
16        header.meta_len = checked_len(metadata.len())?;
17        header.body_len = checked_len(body.len())?;
18        header.packet_len()?;
19        Ok(Self {
20            header,
21            metadata,
22            body,
23        })
24    }
25
26    pub fn to_bytes(&self) -> Result<Vec<u8>, NnrpError> {
27        let packet_len = self.header.packet_len()?;
28        let mut bytes = Vec::with_capacity(packet_len);
29        bytes.extend_from_slice(&self.header.to_bytes()?);
30        bytes.extend_from_slice(&self.metadata);
31        bytes.extend_from_slice(&self.body);
32        Ok(bytes)
33    }
34
35    pub fn from_parts(
36        header: CommonHeader,
37        metadata: Vec<u8>,
38        body: Vec<u8>,
39    ) -> Result<Self, NnrpError> {
40        let declared_len = header.packet_len()?;
41        let actual_len = COMMON_HEADER_LEN + metadata.len() + body.len();
42        if declared_len != actual_len {
43            return Err(NnrpError::PacketLengthMismatch {
44                declared: declared_len,
45                actual: actual_len,
46            });
47        }
48
49        Ok(Self {
50            header,
51            metadata,
52            body,
53        })
54    }
55}
56
57fn checked_len(value: usize) -> Result<u32, NnrpError> {
58    value
59        .try_into()
60        .map_err(|_| NnrpError::MessageLengthOverflow)
61}