mod packet_kind;
use serde::{Deserialize, Serialize};
use itertools::Itertools;
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpStream, ToSocketAddrs, UdpSocket};
use std::sync::atomic::{AtomicU16, Ordering};
use crate::bytes::Bytes;
use crate::error::{Error, ErrorKind};
use crate::ron::{FromRon, ToRon};
pub use packet_kind::PacketKind;
const PACKET_DESCRIPTION_SIZE: u16 = 4;
static mut MAX_PACKET_SIZE: AtomicU16 = AtomicU16::new(1024);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Packet {
size: u16,
kind: PacketKind,
content: Bytes,
}
impl ToRon for Packet {}
impl FromRon<'_> for Packet {}
impl Default for Packet {
fn default() -> Self {
Packet {
size: Packet::description_size(),
kind: PacketKind::Empty,
content: Bytes::empty(),
}
}
}
impl TryFrom<Bytes> for Packet {
type Error = Error;
fn try_from(value: Bytes) -> Result<Self, Self::Error> {
if value
.get((Packet::description_size() - 1) as usize)
.is_none()
{
return Err(Error::new(
ErrorKind::InvalidBufferSize,
Some(
"impl TryFrom<Bytes> for Packet requires buffer of length of at least 4 bytes."
.to_string(),
),
));
}
let size = value.len();
let kind = PacketKind::try_from(&value[2..4])?;
let content = value[4..size].to_vec();
Ok(Packet {
size: size as u16,
kind,
content: content.into(),
})
}
}
impl TryFrom<&Bytes> for Packet {
type Error = Error;
fn try_from(value: &Bytes) -> Result<Self, Self::Error> {
if value
.get((Packet::description_size() - 1) as usize)
.is_none()
{
return Err(Error::new(
ErrorKind::InvalidBufferSize,
Some(
"impl TryFrom<Bytes> for Packet requires buffer of length of at least 4 bytes."
.to_string(),
),
));
}
let size = value.len();
let kind = PacketKind::try_from(&value[2..4])?;
let content = value[4..size].to_vec();
Ok(Packet {
size: size as u16,
kind,
content: content.into(),
})
}
}
impl TryFrom<&[u8]> for Packet {
type Error = Error;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
if value
.get((Packet::description_size() - 1) as usize)
.is_none()
{
return Err(Error::new(
ErrorKind::InvalidBufferSize,
Some(
"impl TryFrom<Bytes> for Packet requires buffer of length of at least 4 bytes."
.to_string(),
),
));
}
let size = value.len();
let kind = PacketKind::try_from(&value[2..4])?;
let content = value[4..size].to_vec();
Ok(Packet {
size: size as u16,
kind,
content: content.into(),
})
}
}
impl From<Packet> for Bytes {
fn from(mut value: Packet) -> Self {
let mut bytes = Bytes::empty();
bytes.append(&mut value.size.into());
bytes.append(&mut value.kind.into());
bytes.append(&mut value.content);
bytes
}
}
impl Packet {
pub fn new(kind: PacketKind, content: Bytes) -> Result<Self, Error> {
let size = Packet::description_size() + content.len() as u16;
if size > Packet::max_size() {
return Err(Error::new(
ErrorKind::TooBigPacket,
Some("Created Packet would be bigger than MAX_PACKET_SIZE.".to_string()),
));
}
Ok(Packet {
size: size as u16,
kind,
content,
})
}
pub fn new_unchecked(kind: PacketKind, content: Bytes) -> Self {
let size = Packet::description_size() + content.len() as u16;
Packet {
size: size as u16,
kind,
content,
}
}
pub fn send(self, stream: &mut TcpStream) -> Result<(), Error> {
let packet_bytes: Bytes = self.into();
let packet_buff = packet_bytes.as_slice();
if let Err(e) = stream.write(packet_buff) {
let packet = Packet::try_from(packet_buff)?;
return Err(Error::new(
ErrorKind::WritingToStreamFailed,
Some(format!(
"Failed to write packet to stream.\n{}\n{}",
packet.to_ron_pretty(None)?,
e,
)),
));
}
Ok(())
}
pub fn send_to<A>(self, socket: UdpSocket, address: A) -> Result<(), Error>
where
A: ToSocketAddrs,
{
let packet_bytes: Bytes = self.into();
let packet_buff = packet_bytes.as_slice();
if let Err(e) = socket.send_to(packet_buff, address) {
let packet = Packet::try_from(packet_buff)?;
return Err(Error::new(
ErrorKind::SendingToAddressFailed,
Some(format!(
"Failed to send packet to address.\n{}\n{}",
packet.to_ron_pretty(None)?,
e,
)),
));
}
Ok(())
}
pub fn send_to_connected(self, socket: UdpSocket) -> Result<(), Error> {
let packet_bytes: Bytes = self.into();
let packet_buff = packet_bytes.as_slice();
if let Err(e) = socket.send(packet_buff) {
let packet = Packet::try_from(packet_buff)?;
return Err(Error::new(
ErrorKind::SendingToAddressFailed,
Some(format!(
"Failed to send packet to connected socket.\n{}\n{}",
packet.to_ron_pretty(None)?,
e,
)),
));
}
Ok(())
}
pub fn receive(stream: &mut TcpStream) -> Result<Packet, Error> {
let mut size_buff = vec![0_u8; 2];
if let Err(e) = stream.read_exact(&mut size_buff) {
return Err(Error::new(
ErrorKind::ReadingFromStreamFailed,
Some(format!("Failed to read the size of packet. \n({})", e)),
));
}
let size = u16::try_from(&Bytes::from(size_buff.clone()))?;
let mut buff = vec![0_u8; (size - 2) as usize];
if let Err(e) = stream.read_exact(&mut buff) {
return Err(Error::new(
ErrorKind::ReadingFromStreamFailed,
Some(format!("Failed to read contents of packet. \n({})", e)),
));
}
size_buff.extend(buff);
let buff = size_buff;
Packet::try_from(buff.as_slice())
}
pub fn receive_from(socket: UdpSocket) -> Result<(Packet, SocketAddr), Error> {
let mut buff = vec![0_u8; Packet::max_size().into()];
match socket.recv_from(&mut buff) {
Ok((number_of_byte_read, address)) => {
buff.truncate(number_of_byte_read);
Ok((Packet::try_from(buff.as_slice())?, address))
}
Err(e) => Err(Error::new(
ErrorKind::ReceivingFromAddressFailed,
Some(format!(
"Failed to receive a packet from an address. \n({e})"
)),
)),
}
}
pub fn receive_from_connected(socket: UdpSocket) -> Result<Packet, Error> {
let mut buff = vec![0_u8; Packet::max_size().into()];
match socket.recv(&mut buff) {
Ok(number_of_byte_read) => {
buff.truncate(number_of_byte_read);
Ok(Packet::try_from(buff.as_slice())?)
}
Err(e) => Err(Error::new(
ErrorKind::ReceivingFromAddressFailed,
Some(format!(
"Failed to receive a packet from the connected socket. \n({e})"
)),
)),
}
}
pub fn peek(stream: &mut TcpStream) -> Result<Packet, Error> {
let mut size_buff = vec![0_u8; 2];
if let Err(e) = stream.peek(&mut size_buff) {
return Err(Error::new(
ErrorKind::ReadingFromStreamFailed,
Some(format!("Failed to peek on the size of packet. \n({})", e)),
));
}
let size = u16::try_from(&Bytes::from(size_buff))?;
let mut buff = vec![0_u8; (size) as usize];
if let Err(e) = stream.peek(&mut buff) {
return Err(Error::new(
ErrorKind::ReadingFromStreamFailed,
Some(format!(
"Failed to peek on the contents of packet. \n({})",
e
)),
));
}
Packet::try_from(buff.as_slice())
}
pub fn peek_from(socket: UdpSocket) -> Result<(Self, SocketAddr), Error> {
let mut buff = vec![0_u8; Packet::max_size().into()];
match socket.peek_from(&mut buff) {
Ok((number_of_byte_read, address)) => {
buff.truncate(number_of_byte_read);
Ok((Packet::try_from(buff.as_slice())?, address))
}
Err(e) => Err(Error::new(
ErrorKind::ReceivingFromAddressFailed,
Some(format!(
"Failed to receive a packet from the address. \n({e})"
)),
)),
}
}
pub fn peek_from_connected(socket: UdpSocket) -> Result<Self, Error> {
let mut buff = vec![0_u8; Packet::max_size().into()];
match socket.peek(&mut buff) {
Ok(number_of_byte_read) => {
buff.truncate(number_of_byte_read);
Ok(Packet::try_from(buff.as_slice())?)
}
Err(e) => Err(Error::new(
ErrorKind::ReceivingFromAddressFailed,
Some(format!(
"Failed to receive a packet from the connected socket. \n({e})"
)),
)),
}
}
pub fn number_of_packets(length: usize) -> u32 {
let mut number_of_packets = length / (Packet::max_content_size() as usize);
if length % (Packet::max_content_size() as usize) != 0 {
number_of_packets += 1;
}
number_of_packets as u32
}
pub fn split_to_max_packet_size(buffer: Bytes) -> Vec<Bytes> {
let vectored_content: Vec<Bytes> = buffer
.into_iter()
.chunks(Packet::max_content_size() as usize)
.into_iter()
.map(|chunk| chunk.collect::<Vec<u8>>().into())
.collect::<Vec<Bytes>>();
vectored_content
}
pub fn size(&self) -> u16 {
self.size
}
pub fn kind(&self) -> PacketKind {
self.kind.clone()
}
pub fn content(&self) -> Bytes {
self.content.clone()
}
pub fn content_ref(&self) -> &Bytes {
&self.content
}
pub fn content_mut(&mut self) -> &mut Bytes {
&mut self.content
}
pub fn content_move(self) -> Bytes {
self.content
}
pub fn max_size() -> u16 {
unsafe { MAX_PACKET_SIZE.load(Ordering::SeqCst) }
}
pub fn set_max_size(size: u16) {
unsafe {
MAX_PACKET_SIZE.store(size, Ordering::SeqCst);
}
}
pub const fn description_size() -> u16 {
PACKET_DESCRIPTION_SIZE
}
pub fn max_content_size() -> u16 {
Packet::max_size() - Packet::description_size()
}
}