classicube_relay/packet/
start.rs1use std::io::{Read, Write};
2
3use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
4
5use super::{FlagsError, Packet, ScopeError, flags::Flags, scope::Scope};
6
7#[derive(Debug, thiserror::Error)]
8pub enum StartPacketError {
9 #[error("wrong data_part len")]
10 DataPartLength,
11
12 #[error("couldn't read full data_part")]
13 ReadFullDataPart,
14
15 #[error(transparent)]
16 Flags(#[from] FlagsError),
17
18 #[error(transparent)]
19 Scope(#[from] ScopeError),
20
21 #[error(transparent)]
22 Io(#[from] std::io::Error),
23}
24type Result<T> = std::result::Result<T, StartPacketError>;
25
26#[derive(Debug, PartialEq, Eq)]
27pub struct StartPacket {
28 pub stream_id: u8,
29 pub scope: Scope,
31 pub data_length: u16,
32 pub data_part: Vec<u8>,
34}
35impl StartPacket {
36 pub const DATA_PART_LENGTH: usize = 64 - 2 * 2 - 1;
37
38 pub fn new<S: Into<Scope>>(
39 stream_id: u8,
40 scope: S,
41 data_length: u16,
42 data_part: Vec<u8>,
43 ) -> Result<Self> {
44 if data_part.len() != Self::DATA_PART_LENGTH {
45 return Err(StartPacketError::DataPartLength);
46 }
47
48 Ok(Self {
49 stream_id,
50 scope: scope.into(),
51 data_length,
52 data_part,
53 })
54 }
55
56 pub fn new_reader<S: Into<Scope>>(
57 stream_id: u8,
58 scope: S,
59 data_length: u16,
60 data_stream: &mut impl Read,
61 ) -> Result<Self> {
62 let mut data_part = Vec::with_capacity(Packet::DATA_LENGTH);
63
64 let mut buf = [0; Self::DATA_PART_LENGTH];
65 let n = data_stream.read(&mut buf)?;
66
67 data_part.write_all(&buf[..n])?;
68 data_part.resize(Self::DATA_PART_LENGTH, 0);
69
70 Self::new(stream_id, scope, data_length, data_part)
71 }
72
73 pub fn encode(&self) -> Result<Vec<u8>> {
74 let mut data = Vec::with_capacity(Packet::DATA_LENGTH);
75
76 data.write_all(
77 &Flags {
78 is_packet_start: true,
79 stream_id: self.stream_id,
80 }
81 .encode()?,
82 )?;
83 data.write_all(&self.scope.encode()?)?;
84 data.write_u16::<NetworkEndian>(self.data_length)?;
85 data.write_all(&self.data_part)?;
86
87 Ok(data)
88 }
89
90 pub(crate) fn decode(stream_id: u8, data_stream: &mut impl Read) -> Result<Self> {
91 let scope = Scope::decode(data_stream)?;
92 let data_length = data_stream.read_u16::<NetworkEndian>()?;
93
94 let mut data_part = [0; Self::DATA_PART_LENGTH];
95 let n = data_stream.read(&mut data_part)?;
96
97 if n != Self::DATA_PART_LENGTH {
98 return Err(StartPacketError::ReadFullDataPart);
99 }
100
101 Ok(Self {
102 stream_id,
103 scope,
104 data_length,
105 data_part: data_part.to_vec(),
106 })
107 }
108}