use std::net::SocketAddr;
use smol::channel::{Sender, TrySendError};
use naia_socket_shared::IdentityToken;
use crate::NaiaServerSocketError;
pub trait AuthSender: AuthSenderClone + Send + Sync {
fn accept(
&self,
address: &SocketAddr,
identity_token: &IdentityToken,
) -> Result<(), NaiaServerSocketError>;
fn reject(&self, address: &SocketAddr) -> Result<(), NaiaServerSocketError>;
}
#[derive(Clone)]
pub struct AuthSenderImpl {
channel_sender: Sender<(SocketAddr, Option<IdentityToken>)>,
}
impl AuthSenderImpl {
pub fn new(channel_sender: Sender<(SocketAddr, Option<IdentityToken>)>) -> Self {
Self { channel_sender }
}
fn send(
&self,
address: &SocketAddr,
accept: Option<IdentityToken>,
) -> Result<(), NaiaServerSocketError> {
self.channel_sender
.try_send((*address, accept))
.map_err(|err| match err {
TrySendError::Full(_) => unreachable!("the channel is expected to be unbound"),
TrySendError::Closed(_) => NaiaServerSocketError::SendError(*address),
})
}
}
impl AuthSender for AuthSenderImpl {
fn accept(
&self,
address: &SocketAddr,
identity_token: &IdentityToken,
) -> Result<(), NaiaServerSocketError> {
self.send(address, Some(identity_token.clone()))
}
fn reject(&self, address: &SocketAddr) -> Result<(), NaiaServerSocketError> {
self.send(address, None)
}
}
pub trait AuthSenderClone {
fn clone_box(&self) -> Box<dyn AuthSender>;
}
impl<T: 'static + AuthSender + Clone> AuthSenderClone for T {
fn clone_box(&self) -> Box<dyn AuthSender> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn AuthSender> {
fn clone(&self) -> Box<dyn AuthSender> {
AuthSenderClone::clone_box(self.as_ref())
}
}