nimble_blob_stream/
protocol_front.rs1use crate::protocol::{AckChunkData, SetChunkData, StartTransferData, TransferId};
6use flood_rs::{ReadOctetStream, WriteOctetStream};
7use std::fmt::Display;
8use std::io;
9use std::io::ErrorKind;
10
11#[derive(Debug, Clone, Eq, PartialEq)]
12pub struct SetChunkFrontData {
13 pub transfer_id: TransferId,
14 pub data: SetChunkData,
15}
16
17impl SetChunkFrontData {
18 #[allow(clippy::cast_possible_truncation)]
23 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
24 self.transfer_id.to_stream(stream)?;
25 self.data.to_stream(stream)?;
26 Ok(())
27 }
28
29 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
34 Ok(Self {
35 transfer_id: TransferId::from_stream(stream)?,
36 data: SetChunkData::from_stream(stream)?,
37 })
38 }
39}
40
41#[derive(Debug, Clone, Eq, PartialEq)]
42pub enum SenderToReceiverFrontCommands {
43 SetChunk(SetChunkFrontData),
44 StartTransfer(StartTransferData),
45}
46
47impl Display for SenderToReceiverFrontCommands {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 match self {
50 Self::SetChunk(set_chunk_data) => write!(
51 f,
52 "set_chunk transfer{} index:{} chunk_size:{}",
53 set_chunk_data.transfer_id.0,
54 set_chunk_data.data.chunk_index,
55 set_chunk_data.data.payload.len()
56 ),
57 Self::StartTransfer(transfer_data) => {
58 write!(f, "start transfer {transfer_data:?}")
59 }
60 }
61 }
62}
63
64#[repr(u8)]
65enum SenderToReceiverFrontCommand {
66 SetChunk = 0x01,
67 StartTransfer = 0x02,
68}
69
70impl TryFrom<u8> for SenderToReceiverFrontCommand {
71 type Error = io::Error;
72
73 fn try_from(value: u8) -> io::Result<Self> {
74 Ok(match value {
75 0x01 => Self::SetChunk,
76 0x02 => Self::StartTransfer,
77 _ => Err(io::Error::new(
78 ErrorKind::InvalidData,
79 format!("Unknown SenderToReceiverFrontCommand {value}"),
80 ))?,
81 })
82 }
83}
84
85impl SenderToReceiverFrontCommands {
86 #[must_use]
87 pub const fn to_octet(&self) -> u8 {
88 match self {
89 Self::SetChunk(_) => SenderToReceiverFrontCommand::SetChunk as u8,
90 Self::StartTransfer(_) => SenderToReceiverFrontCommand::StartTransfer as u8,
91 }
92 }
93
94 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
100 stream.write_u8(self.to_octet())?;
101 match self {
102 Self::SetChunk(set_chunk_header) => set_chunk_header.to_stream(stream),
103 Self::StartTransfer(transfer_data) => transfer_data.to_stream(stream),
104 }
105 }
106
107 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
112 let command_value = stream.read_u8()?;
113 let command = SenderToReceiverFrontCommand::try_from(command_value)?;
114 let x = match command {
115 SenderToReceiverFrontCommand::SetChunk => {
116 Self::SetChunk(SetChunkFrontData::from_stream(stream)?)
117 }
118 SenderToReceiverFrontCommand::StartTransfer => {
119 Self::StartTransfer(StartTransferData::from_stream(stream)?)
120 }
121 };
122 Ok(x)
123 }
124}
125
126#[repr(u8)]
127enum ReceiverToSenderFrontCommand {
128 AckStart = 0x03,
129 AckChunk = 0x04,
130}
131
132impl TryFrom<u8> for ReceiverToSenderFrontCommand {
133 type Error = io::Error;
134
135 fn try_from(value: u8) -> io::Result<Self> {
136 Ok(match value {
137 0x03 => Self::AckStart,
138 0x04 => Self::AckChunk,
139 _ => Err(io::Error::new(
140 ErrorKind::InvalidData,
141 format!("Unknown ReceiverToSenderFrontCommand {value}"),
142 ))?,
143 })
144 }
145}
146
147#[derive(Debug, Clone, Eq, PartialEq)]
148pub struct AckChunkFrontData {
149 pub transfer_id: TransferId,
150 pub data: AckChunkData,
151}
152
153impl AckChunkFrontData {
154 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
159 self.transfer_id.to_stream(stream)?;
160 self.data.to_stream(stream)
161 }
162
163 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
168 Ok(Self {
169 transfer_id: TransferId::from_stream(stream)?,
170 data: AckChunkData::from_stream(stream)?,
171 })
172 }
173}
174
175#[derive(Debug, Clone, Eq, PartialEq)]
176pub enum ReceiverToSenderFrontCommands {
177 AckChunk(AckChunkFrontData),
178 AckStart(u16),
179}
180
181impl ReceiverToSenderFrontCommands {
182 #[must_use]
183 pub const fn to_octet(&self) -> u8 {
184 match self {
185 Self::AckChunk(_) => ReceiverToSenderFrontCommand::AckChunk as u8,
186 Self::AckStart(_) => ReceiverToSenderFrontCommand::AckStart as u8,
187 }
188 }
189
190 pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
195 stream.write_u8(self.to_octet())?;
196 match self {
197 Self::AckChunk(set_chunk_header) => set_chunk_header.to_stream(stream),
198 Self::AckStart(transfer_id) => stream.write_u16(*transfer_id),
199 }
200 }
201
202 pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
207 let command_value = stream.read_u8()?;
208 let command = ReceiverToSenderFrontCommand::try_from(command_value)?;
209 let x = match command {
210 ReceiverToSenderFrontCommand::AckChunk => Self::AckChunk(AckChunkFrontData {
211 transfer_id: TransferId::from_stream(stream)?,
212 data: AckChunkData::from_stream(stream)?,
213 }),
214 ReceiverToSenderFrontCommand::AckStart => Self::AckStart(stream.read_u16()?),
215 };
216 Ok(x)
217 }
218}