use crate::LinkType;
use async_std::{
io::{self, prelude::ReadExt},
net::TcpStream,
};
use bincode::{deserialize, serialize};
use byteorder::{BigEndian, ByteOrder};
use netmod::Frame;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub(crate) enum Packet {
Hello { port: u16, _type: LinkType },
Ack,
Frame(Frame),
}
impl Packet {
pub(crate) fn serialize(&self) -> Vec<u8> {
let mut vec = serialize(self).unwrap();
let mut buf = vec![0; 8];
BigEndian::write_u64(&mut buf, vec.len() as u64);
buf.append(&mut vec);
buf
}
}
pub(crate) struct PacketBuilder<'s> {
stream: &'s mut TcpStream,
data: Option<Vec<u8>>,
}
impl<'s> PacketBuilder<'s> {
pub(crate) fn new(stream: &'s mut TcpStream) -> Self {
Self { stream, data: None }
}
pub(crate) async fn parse(&mut self) -> io::Result<()> {
let mut len_buf = [0; 8];
self.stream.read_exact(&mut len_buf).await?;
let len = BigEndian::read_u64(&len_buf);
let mut data_buf = vec![0; len as usize];
self.stream.read_exact(&mut data_buf).await?;
self.data = Some(data_buf);
Ok(())
}
pub(crate) fn build(self) -> Option<Packet> {
self.data.and_then(|vec| deserialize(&vec).ok())
}
}