use std::marker::PhantomData;
use bincode::Options as _;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::{
packet::PacketPool,
runtime::Runtime,
unreliable_channel::{self, UnreliableChannel, MAX_MESSAGE_LEN},
};
#[derive(Debug, Error)]
pub enum SendError {
#[error("unreliable channel error: {0}")]
UnreliableChannelError(#[from] unreliable_channel::SendError),
#[error("bincode serialization error: {0}")]
BincodeError(bincode::Error),
}
#[derive(Debug, Error)]
pub enum RecvError {
#[error("unreliable channel error: {0}")]
UnreliableChannelError(#[from] unreliable_channel::RecvError),
#[error("bincode serialization error: {0}")]
BincodeError(bincode::Error),
}
pub struct UnreliableBincodeChannel<R, P>
where
R: Runtime,
P: PacketPool,
{
channel: UnreliableChannel<R, P>,
buffer: Box<[u8]>,
}
impl<R, P> UnreliableBincodeChannel<R, P>
where
R: Runtime,
P: PacketPool,
{
pub fn new(channel: UnreliableChannel<R, P>, max_message_len: u16) -> Self {
UnreliableBincodeChannel {
channel,
buffer: vec![0; max_message_len.min(MAX_MESSAGE_LEN) as usize].into_boxed_slice(),
}
}
pub async fn send<T: Serialize>(&mut self, msg: &T) -> Result<(), SendError> {
let bincode_config = self.bincode_config();
let mut w = &mut self.buffer[..];
bincode_config
.serialize_into(&mut w, msg)
.map_err(SendError::BincodeError)?;
let remaining = w.len();
let written = self.buffer.len() - remaining;
Ok(self.channel.send(&self.buffer[0..written]).await?)
}
pub async fn flush(&mut self) -> Result<(), SendError> {
Ok(self.channel.flush().await?)
}
pub async fn recv<'a, T: Deserialize<'a>>(&'a mut self) -> Result<T, RecvError> {
let bincode_config = self.bincode_config();
let msg = self.channel.recv().await?;
bincode_config
.deserialize(msg)
.map_err(RecvError::BincodeError)
}
fn bincode_config(&self) -> impl bincode::Options + Copy {
bincode::options().with_limit(self.buffer.len() as u64)
}
}
pub struct UnreliableTypedChannel<T, R, P>
where
R: Runtime,
P: PacketPool,
{
channel: UnreliableBincodeChannel<R, P>,
_phantom: PhantomData<T>,
}
impl<T, R, P> UnreliableTypedChannel<T, R, P>
where
R: Runtime,
P: PacketPool,
{
pub fn new(channel: UnreliableBincodeChannel<R, P>) -> Self {
UnreliableTypedChannel {
channel,
_phantom: PhantomData,
}
}
pub async fn flush(&mut self) -> Result<(), SendError> {
self.channel.flush().await
}
}
impl<T, R, P> UnreliableTypedChannel<T, R, P>
where
T: Serialize,
R: Runtime,
P: PacketPool,
{
pub async fn send(&mut self, msg: &T) -> Result<(), SendError> {
self.channel.send(msg).await
}
}
impl<'a, T, R, P> UnreliableTypedChannel<T, R, P>
where
T: Deserialize<'a>,
R: Runtime,
P: PacketPool,
{
pub async fn recv(&'a mut self) -> Result<T, RecvError> {
self.channel.recv().await
}
}