blob_stream/
protocol_front.rs1use crate::protocol::{AckChunkData, SetChunkData, StartTransferData, TransferId};
6use flood_rs::{ReadOctetStream, WriteOctetStream};
7use std::io;
8use std::io::ErrorKind;
9
10#[derive(Debug, Clone, Eq, PartialEq)]
11pub struct SetChunkFrontData {
12 pub transfer_id: TransferId,
13 pub data: SetChunkData,
14}
15
16impl SetChunkFrontData {
17 #[allow(clippy::cast_possible_truncation)]
22 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
23 self.transfer_id.to_stream(stream)?;
24 self.data.to_stream(stream)?;
25 Ok(())
26 }
27
28 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
33 Ok(Self {
34 transfer_id: TransferId::from_stream(stream)?,
35 data: SetChunkData::from_stream(stream)?,
36 })
37 }
38}
39
40#[derive(Debug, Clone, Eq, PartialEq)]
41pub enum SenderToReceiverFrontCommands {
42 SetChunk(SetChunkFrontData),
43 StartTransfer(StartTransferData),
44}
45
46#[repr(u8)]
47enum SenderToReceiverFrontCommand {
48 SetChunk = 0x01,
49 StartTransfer = 0x02,
50}
51
52impl TryFrom<u8> for SenderToReceiverFrontCommand {
53 type Error = io::Error;
54
55 fn try_from(value: u8) -> io::Result<Self> {
56 match value {
57 0x01 => Ok(Self::SetChunk),
58 0x02 => Ok(Self::StartTransfer),
59 _ => Err(io::Error::new(
60 io::ErrorKind::InvalidData,
61 format!("Unknown command {value}"),
62 )),
63 }
64 }
65}
66
67impl SenderToReceiverFrontCommands {
68 #[must_use]
69 pub const fn to_octet(&self) -> u8 {
70 match self {
71 Self::SetChunk(_) => SenderToReceiverFrontCommand::SetChunk as u8,
72 Self::StartTransfer(_) => SenderToReceiverFrontCommand::StartTransfer as u8,
73 }
74 }
75
76 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
82 stream.write_u8(self.to_octet())?;
83 match self {
84 Self::SetChunk(set_chunk_header) => set_chunk_header.to_stream(stream),
85 Self::StartTransfer(transfer_data) => transfer_data.to_stream(stream),
86 }
87 }
88
89 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
94 let command_value = stream.read_u8()?;
95 let command = SenderToReceiverFrontCommand::try_from(command_value)?;
96 let x = match command {
97 SenderToReceiverFrontCommand::SetChunk => {
98 Self::SetChunk(SetChunkFrontData::from_stream(stream)?)
99 }
100 SenderToReceiverFrontCommand::StartTransfer => {
101 Self::StartTransfer(StartTransferData::from_stream(stream)?)
102 }
103 };
104 Ok(x)
105 }
106}
107
108#[repr(u8)]
109enum ReceiverToSenderFrontCommand {
110 AckChunk = 0x02,
111 AckStart = 0x03,
112}
113
114impl TryFrom<u8> for ReceiverToSenderFrontCommand {
115 type Error = io::Error;
116
117 fn try_from(value: u8) -> io::Result<Self> {
118 match value {
119 0x02 => Ok(Self::AckChunk),
120 0x03 => Ok(Self::AckStart),
121 _ => Err(io::Error::new(
122 ErrorKind::InvalidData,
123 format!("Unknown command {value}"),
124 )),
125 }
126 }
127}
128
129#[derive(Debug, Clone, Eq, PartialEq)]
130pub struct AckChunkFrontData {
131 pub transfer_id: TransferId,
132 pub data: AckChunkData,
133}
134
135impl AckChunkFrontData {
136 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
141 self.transfer_id.to_stream(stream)?;
142 self.data.to_stream(stream)
143 }
144
145 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
150 Ok(Self {
151 transfer_id: TransferId::from_stream(stream)?,
152 data: AckChunkData::from_stream(stream)?,
153 })
154 }
155}
156
157#[derive(Debug, Clone, Eq, PartialEq)]
158pub enum ReceiverToSenderFrontCommands {
159 AckChunk(AckChunkFrontData),
160 AckStart(u16),
161}
162
163impl ReceiverToSenderFrontCommands {
164 #[must_use]
165 pub const fn to_octet(&self) -> u8 {
166 match self {
167 Self::AckChunk(_) => ReceiverToSenderFrontCommand::AckChunk as u8,
168 Self::AckStart(_) => ReceiverToSenderFrontCommand::AckStart as u8,
169 }
170 }
171
172 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
177 stream.write_u8(self.to_octet())?;
178 match self {
179 Self::AckChunk(set_chunk_header) => set_chunk_header.to_stream(stream),
180 Self::AckStart(transfer_id) => stream.write_u16(*transfer_id),
181 }
182 }
183
184 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
189 let command_value = stream.read_u8()?;
190 let command = ReceiverToSenderFrontCommand::try_from(command_value)?;
191 let x = match command {
192 ReceiverToSenderFrontCommand::AckChunk => Self::AckChunk(AckChunkFrontData {
193 transfer_id: TransferId::from_stream(stream)?,
194 data: AckChunkData::from_stream(stream)?,
195 }),
196 ReceiverToSenderFrontCommand::AckStart => Self::AckStart(stream.read_u16()?),
197 };
198 Ok(x)
199 }
200}