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}