1use core::convert;
5
6use crate::{
7 channel::Channel,
8 command::Command,
9 error::{ParseError, SerializationError},
10 util::{Parser, Serializer},
11};
12
13#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
19pub enum Packet<T: AsRef<[u8]>> {
20 Initialization(InitializationPacket<T>),
22 Continuation(ContinuationPacket<T>),
24}
25
26impl<T: AsRef<[u8]>> Packet<T> {
27 pub fn channel(&self) -> Channel {
29 match self {
30 Self::Initialization(packet) => packet.channel,
31 Self::Continuation(packet) => packet.channel,
32 }
33 }
34
35 pub fn packet_type(&self) -> PacketType {
37 match self {
38 Self::Initialization(_) => PacketType::Initialization,
39 Self::Continuation(_) => PacketType::Continuation,
40 }
41 }
42
43 pub fn serialize(&self, buffer: &mut [u8]) -> Result<usize, SerializationError> {
45 match self {
46 Self::Initialization(packet) => packet.serialize(buffer),
47 Self::Continuation(packet) => packet.serialize(buffer),
48 }
49 }
50}
51
52impl<T: AsRef<[u8]>> From<ContinuationPacket<T>> for Packet<T> {
53 fn from(packet: ContinuationPacket<T>) -> Self {
54 Self::Continuation(packet)
55 }
56}
57
58impl<T: AsRef<[u8]>> From<InitializationPacket<T>> for Packet<T> {
59 fn from(packet: InitializationPacket<T>) -> Self {
60 Self::Initialization(packet)
61 }
62}
63
64impl<'a, T: AsRef<[u8]> + convert::TryFrom<&'a [u8]>> convert::TryFrom<&'a [u8]> for Packet<T> {
65 type Error = ParseError;
66
67 fn try_from(data: &'a [u8]) -> Result<Self, Self::Error> {
68 if data.len() < 5 {
69 return Err(ParseError::NotEnoughData);
70 }
71 let command_or_sequence = data[4];
72
73 if command_or_sequence.leading_ones() > 0 {
74 InitializationPacket::try_from(data).map(From::from)
75 } else {
76 ContinuationPacket::try_from(data).map(From::from)
77 }
78 }
79}
80
81#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
87pub enum PacketType {
88 Initialization,
90 Continuation,
92}
93
94pub const INITIALIZATION_HEADER_SIZE: usize = 7;
100
101#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
107pub struct InitializationPacket<T: AsRef<[u8]>> {
108 pub channel: Channel,
110 pub command: Command,
112 pub length: u16,
114 pub data: T,
116}
117
118impl<T: AsRef<[u8]>> InitializationPacket<T> {
119 pub fn serialize(&self, buffer: &mut [u8]) -> Result<usize, SerializationError> {
121 let mut serializer = Serializer::new(buffer);
122 serializer.push_slice(&self.channel.to_bytes())?;
123 serializer.push_slice(&[u8::from(self.command) | 0b1000_0000])?;
124 serializer.push_slice(&self.length.to_be_bytes())?;
125 serializer.push_slice(self.data.as_ref())?;
126 Ok(serializer.bytes_written())
127 }
128}
129
130impl<T: AsRef<[u8]>> convert::TryFrom<Packet<T>> for InitializationPacket<T> {
131 type Error = ParseError;
132
133 fn try_from(packet: Packet<T>) -> Result<Self, Self::Error> {
134 if let Packet::Initialization(packet) = packet {
135 Ok(packet)
136 } else {
137 Err(ParseError::InvalidPacketType {
138 expected: PacketType::Initialization,
139 actual: packet.packet_type(),
140 })
141 }
142 }
143}
144
145impl<'a, T: AsRef<[u8]> + convert::TryFrom<&'a [u8]>> convert::TryFrom<&'a [u8]>
146 for InitializationPacket<T>
147{
148 type Error = ParseError;
149
150 fn try_from(data: &'a [u8]) -> Result<Self, Self::Error> {
151 let mut parser = Parser::new(data);
152 let channel = parser.take_into()?;
153 let command = parser.take()?;
154 let length = parser.take_array()?;
155 let rest = parser.into_rest();
156
157 if command.leading_ones() == 0 {
158 return Err(ParseError::InvalidPacketType {
159 expected: PacketType::Initialization,
160 actual: PacketType::Continuation,
161 });
162 }
163
164 Ok(InitializationPacket {
165 channel,
166 command: Command::from(command & 0b0111_1111),
167 length: u16::from_be_bytes(length),
168 data: T::try_from(rest).map_err(|_| ParseError::BufferCreationFailed)?,
169 })
170 }
171}
172
173pub const CONTINUATION_HEADER_SIZE: usize = 5;
179
180#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
186pub struct ContinuationPacket<T: AsRef<[u8]>> {
187 pub channel: Channel,
189 pub sequence: u8,
191 pub data: T,
193}
194
195impl<T: AsRef<[u8]>> ContinuationPacket<T> {
196 pub fn serialize(&self, buffer: &mut [u8]) -> Result<usize, SerializationError> {
198 let mut serializer = Serializer::new(buffer);
199 serializer.push_slice(&self.channel.to_bytes())?;
200 serializer.push_slice(&[self.sequence])?;
201 serializer.push_slice(self.data.as_ref())?;
202 Ok(serializer.bytes_written())
203 }
204}
205
206impl<T: AsRef<[u8]>> convert::TryFrom<Packet<T>> for ContinuationPacket<T> {
207 type Error = ParseError;
208
209 fn try_from(packet: Packet<T>) -> Result<Self, Self::Error> {
210 if let Packet::Continuation(packet) = packet {
211 Ok(packet)
212 } else {
213 Err(ParseError::InvalidPacketType {
214 expected: PacketType::Continuation,
215 actual: packet.packet_type(),
216 })
217 }
218 }
219}
220
221impl<'a, T: AsRef<[u8]> + convert::TryFrom<&'a [u8]>> convert::TryFrom<&'a [u8]>
222 for ContinuationPacket<T>
223{
224 type Error = ParseError;
225
226 fn try_from(data: &'a [u8]) -> Result<Self, Self::Error> {
227 let mut parser = Parser::new(data);
228 let channel = parser.take_into()?;
229 let sequence = parser.take()?;
230 let rest = parser.into_rest();
231
232 if sequence.leading_ones() > 0 {
233 return Err(ParseError::InvalidPacketType {
234 expected: PacketType::Continuation,
235 actual: PacketType::Initialization,
236 });
237 }
238
239 Ok(ContinuationPacket {
240 channel,
241 sequence,
242 data: T::try_from(rest).map_err(|_| ParseError::BufferCreationFailed)?,
243 })
244 }
245}
246
247#[cfg(test)]
248mod test {
249 use std::convert::TryFrom;
250
251 use quickcheck::{Arbitrary, TestResult};
252
253 use super::{ContinuationPacket, InitializationPacket, Packet, PacketType};
254
255 impl Arbitrary for Packet<Vec<u8>> {
256 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
257 match PacketType::arbitrary(g) {
258 PacketType::Initialization => Packet::Initialization(Arbitrary::arbitrary(g)),
259 PacketType::Continuation => Packet::Continuation(Arbitrary::arbitrary(g)),
260 }
261 }
262
263 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
264 match self {
265 Packet::Initialization(packet) => Box::new(packet.shrink().map(From::from)),
266 Packet::Continuation(packet) => Box::new(packet.shrink().map(From::from)),
267 }
268 }
269 }
270
271 impl Arbitrary for PacketType {
272 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
273 *g.choose(&[PacketType::Initialization, PacketType::Continuation])
274 .unwrap()
275 }
276 }
277
278 impl Arbitrary for InitializationPacket<Vec<u8>> {
279 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
280 Self {
281 channel: Arbitrary::arbitrary(g),
282 command: Arbitrary::arbitrary(g),
283 length: Arbitrary::arbitrary(g),
284 data: Arbitrary::arbitrary(g),
285 }
286 }
287
288 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
289 let channel = self.channel;
290 let command = self.command;
291 let length = self.length;
292 Box::new(self.data.shrink().map(move |data| Self {
293 channel,
294 command,
295 length,
296 data,
297 }))
298 }
299 }
300
301 impl Arbitrary for ContinuationPacket<Vec<u8>> {
302 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
303 Self {
304 channel: Arbitrary::arbitrary(g),
305 sequence: Arbitrary::arbitrary(g),
306 data: Arbitrary::arbitrary(g),
307 }
308 }
309
310 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
311 let channel = self.channel;
312 let sequence = self.sequence;
313 Box::new(self.data.shrink().map(move |data| Self {
314 channel,
315 sequence,
316 data,
317 }))
318 }
319 }
320
321 quickcheck::quickcheck! {
322 fn parse_init(data: Vec<u8>) -> bool {
323 let _ = InitializationPacket::<Vec<u8>>::try_from(data.as_slice());
324 true
325 }
326 }
327
328 quickcheck::quickcheck! {
329 fn serialize_init(packet: InitializationPacket<Vec<u8>>) -> bool {
330 let mut buffer = vec![0; packet.data.len() + 10];
331 let _ = packet.serialize(&mut buffer);
332 true
333 }
334 }
335
336 quickcheck::quickcheck! {
337 fn serialize_parse_init(packet: InitializationPacket<Vec<u8>>) -> TestResult {
338 if usize::from(packet.length) < packet.data.len() {
339 return TestResult::discard();
340 }
341 if u8::from(packet.command).leading_ones() > 0 {
342 return TestResult::discard();
343 }
344 let mut buffer = vec![0; packet.data.len() + 10];
345 let n = packet.serialize(&mut buffer).unwrap();
346 let parsed = InitializationPacket::try_from(&buffer[..n]).unwrap();
347 TestResult::from_bool(packet == parsed)
348 }
349 }
350
351 quickcheck::quickcheck! {
352 fn parse_cont(data: Vec<u8>) -> bool {
353 let _ = ContinuationPacket::<Vec<u8>>::try_from(data.as_slice());
354 true
355 }
356 }
357
358 quickcheck::quickcheck! {
359 fn serialize_cont(packet: ContinuationPacket<Vec<u8>>) -> bool {
360 let mut buffer = vec![0; packet.data.len() + 10];
361 let _ = packet.serialize(&mut buffer);
362 true
363 }
364 }
365
366 quickcheck::quickcheck! {
367 fn serialize_parse_cont(packet: ContinuationPacket<Vec<u8>>) -> TestResult {
368 if u8::from(packet.sequence).leading_ones() > 0 {
369 return TestResult::discard();
370 }
371 let mut buffer = vec![0; packet.data.len() + 10];
372 let n = packet.serialize(&mut buffer).unwrap();
373 let parsed = ContinuationPacket::try_from(&buffer[..n]).unwrap();
374 TestResult::from_bool(packet == parsed)
375 }
376 }
377}