use std::net::SocketAddr;
use smol::channel::Receiver;
use super::error::NaiaServerSocketError;
#[derive(Clone)]
pub struct PacketReceiver {
inner: Box<dyn PacketReceiverTrait>,
}
impl PacketReceiver {
pub fn new(inner: Box<dyn PacketReceiverTrait>) -> Self {
PacketReceiver { inner }
}
pub fn receive(&mut self) -> Result<Option<(SocketAddr, &[u8])>, NaiaServerSocketError> {
self.inner.receive()
}
}
pub trait PacketReceiverTrait: PacketReceiverClone + Send + Sync {
fn receive(&mut self) -> Result<Option<(SocketAddr, &[u8])>, NaiaServerSocketError>;
}
#[derive(Clone)]
pub struct PacketReceiverImpl {
#[allow(clippy::type_complexity)]
channel_receiver: Receiver<Result<(SocketAddr, Box<[u8]>), NaiaServerSocketError>>,
last_payload: Option<Box<[u8]>>,
}
impl PacketReceiverImpl {
#[allow(clippy::type_complexity)]
pub fn new(
channel_receiver: Receiver<Result<(SocketAddr, Box<[u8]>), NaiaServerSocketError>>,
) -> Self {
PacketReceiverImpl {
channel_receiver,
last_payload: None,
}
}
}
impl PacketReceiverTrait for PacketReceiverImpl {
fn receive(&mut self) -> Result<Option<(SocketAddr, &[u8])>, NaiaServerSocketError> {
match self.channel_receiver.try_recv() {
Ok(result) => match result {
Ok((address, payload)) => {
self.last_payload = Some(payload);
return Ok(Some((address, self.last_payload.as_ref().unwrap())));
}
Err(_) => Ok(None),
},
Err(_) => Ok(None),
}
}
}
pub trait PacketReceiverClone {
fn clone_box(&self) -> Box<dyn PacketReceiverTrait>;
}
impl<T: 'static + PacketReceiverTrait + Clone> PacketReceiverClone for T {
fn clone_box(&self) -> Box<dyn PacketReceiverTrait> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn PacketReceiverTrait> {
fn clone(&self) -> Box<dyn PacketReceiverTrait> {
PacketReceiverClone::clone_box(self.as_ref())
}
}