Решение на Network Packets от Димитър Иринков

Обратно към всички решения

Към профила на Димитър Иринков

Резултати

  • 12 точки от тестове
  • 0 бонус точки
  • 12 точки общо
  • 9 успешни тест(а)
  • 6 неуспешни тест(а)

Код

use std::fmt;
use std::mem;
use std::convert::TryInto;
#[derive(Debug)]
pub enum PacketError {
InvalidPacket,
InvalidChecksum,
UnknownProtocolVersion,
CorruptedMessage,
}
impl fmt::Display for PacketError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PacketError: {:?}", self)
}
}
impl std::error::Error for PacketError {}
#[derive(PartialEq, Debug)]
pub struct Packet<'a> {
protocol: u8,
payload: &'a[u8],
checksum: u32,
}
impl<'a> Packet<'a> {
pub fn from_source(source: &'a[u8], size: u8) -> (Self, &'a[u8]) {
if size == 0 {
panic!();
}
let size = source.len().min(size as usize);
let (payload, left_over) = source.split_at(size);
(Packet {
protocol: 1,
payload: payload,
checksum: payload.iter().map(|&x| x as u32).sum(),
},
left_over)
}
pub fn payload(&self) -> &[u8] {
self.payload
}
pub fn serialize(&self) -> Vec<u8> {
let mut v = Vec::with_capacity(1+1+self.payload.len()+4);
v.push(self.protocol);
v.push(self.payload.len() as u8);
v.extend(self.payload.iter());
v.extend_from_slice(&self.checksum.to_be_bytes());
v
}
pub fn deserialize(bytes: &[u8]) -> Result<(Packet, &[u8]), PacketError> {
let (&protocol,bytes) = bytes.split_first().ok_or(PacketError::InvalidPacket)?;
let (&size, bytes) = bytes.split_first().ok_or(PacketError::InvalidPacket)?;
let (payload, bytes) = bytes.split_at(size as usize);
let (checksum, bytes) = bytes.split_at(mem::size_of::<u32>());
let checksum = u32::from_be_bytes(checksum.try_into().unwrap());
Ok((Packet {
protocol,
payload,
checksum,
},
bytes))
}
}
pub struct PacketSerializer<'a> {
value: Vec<Packet<'a>>,
}
impl<'a> Iterator for PacketSerializer<'a> {
type Item = Packet<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.value.pop()
}
}
pub trait Packetable: Sized {
fn to_packets(&self, packet_size: u8) -> PacketSerializer;
fn to_packet_data(&self, packet_size: u8) -> Vec<u8>;
fn from_packet_data(packet_data: &[u8]) -> Result<Self, PacketError>;
}
impl Packetable for String {
fn to_packets(&self, packet_size: u8) -> PacketSerializer {
let mut v = Vec::new();
let mut bytes = self.as_bytes();
while !bytes.is_empty() {
let (packet, left_over) = Packet::from_source(self.as_bytes(), packet_size);
v.push(packet);
bytes = left_over;
}
v.reverse();
PacketSerializer {
value: v,
}
}
fn to_packet_data(&self, packet_size: u8) -> Vec<u8> {
let packet_serializer = self.to_packets(packet_size);
let mut v = Vec::new();
for packet in packet_serializer {
v.extend(packet.serialize());
}
v
}
fn from_packet_data(packet_data: &[u8]) -> Result<Self, PacketError> {
let (packet, left_over) = Packet::deserialize(packet_data)?;
println!("{:?}", packet);
// Ok(unsafe{String::from_utf8_unchecked(packet.payload().to_vec())})
String::from_utf8(packet.payload().to_vec()).or(Err(PacketError::CorruptedMessage))

Добро начало, още малко ти оставаше да го превърнеш в цикъл и да продължиш итерацията върху left_over. Бих предположил, че ти е свършило времето, но всъщност си го писал доста рано, така че изглежда просто не си се върнал да го оправиш. Жалко.

}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20200111-2173579-1f4hklv/solution)
warning: unused variable: `left_over`
   --> src/lib.rs:117:22
    |
117 |         let (packet, left_over) = Packet::deserialize(packet_data)?;
    |                      ^^^^^^^^^ help: consider prefixing with an underscore: `_left_over`
    |
    = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `left_over`
   --> src/lib.rs:117:22
    |
117 |         let (packet, left_over) = Packet::deserialize(packet_data)?;
    |                      ^^^^^^^^^ help: consider prefixing with an underscore: `_left_over`
    |
    = note: `#[warn(unused_variables)]` on by default

    Finished test [unoptimized + debuginfo] target(s) in 3.69s
     Running target/debug/deps/solution-a73e64ec87929bd0

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/solution_test-38971695424b36d5

running 15 tests
test solution_test::test_construct_packet_from_unicode ... ok
test solution_test::test_construct_packet_no_remainder ... ok
test solution_test::test_construct_packet_with_remainder ... ok
test solution_test::test_construct_packet_with_remainder_cyrillic ... ok
test solution_test::test_consuming_packets ... FAILED
test solution_test::test_deserialize_invalid_packet ... FAILED
test solution_test::test_deserialize_packet ... ok
test solution_test::test_deserialize_unicode_packet ... ok
test solution_test::test_full_roundtrip ... FAILED
test solution_test::test_full_roundtrip_for_zero_size_string ... thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidPacket', src/libcore/result.rs:1165:5
FAILED
test solution_test::test_invalid_packet_combination ... FAILED
test solution_test::test_iterating_packets ... FAILED
test solution_test::test_iterating_packets_for_zero_size_string ... ok
test solution_test::test_serialize_packet ... ok
test solution_test::test_zero_size ... ok

failures:

---- solution_test::test_consuming_packets stdout ----
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Timeout', src/libcore/result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

---- solution_test::test_deserialize_invalid_packet stdout ----
thread 'main' panicked at 'Expression Ok((Packet { protocol: 2, payload: [120, 121, 122], checksum: 363 }, [])) does not match the pattern "Err(PacketError::UnknownProtocolVersion)"', tests/solution_test.rs:147:5

---- solution_test::test_full_roundtrip stdout ----
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Timeout', src/libcore/result.rs:1165:5

---- solution_test::test_full_roundtrip_for_zero_size_string stdout ----
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidPacket', tests/solution_test.rs:221:5

---- solution_test::test_invalid_packet_combination stdout ----
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Timeout', src/libcore/result.rs:1165:5

---- solution_test::test_iterating_packets stdout ----
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Timeout', src/libcore/result.rs:1165:5


failures:
    solution_test::test_consuming_packets
    solution_test::test_deserialize_invalid_packet
    solution_test::test_full_roundtrip
    solution_test::test_full_roundtrip_for_zero_size_string
    solution_test::test_invalid_packet_combination
    solution_test::test_iterating_packets

test result: FAILED. 9 passed; 6 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test solution_test'

История (1 версия и 4 коментара)

Димитър качи първо решение на 29.11.2019 01:58 (преди почти 6 години)