use crate::{Acceptor, Transport};
use std::{
fmt::{self, Debug, Formatter},
future::Future,
pin::Pin,
sync::Arc,
};
#[derive(Debug)]
pub struct BoxedAcceptError(String);
impl fmt::Display for BoxedAcceptError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
impl std::error::Error for BoxedAcceptError {}
type BoxedTransport = Box<dyn Transport>;
type AcceptFuture = Pin<Box<dyn Future<Output = Result<BoxedTransport, BoxedAcceptError>> + Send>>;
trait DynAcceptor<Input: Transport>: Send + Sync {
fn dyn_accept(&self, input: Input) -> AcceptFuture;
fn is_secure(&self) -> bool;
}
impl<Input, A> DynAcceptor<Input> for A
where
Input: Transport,
A: Acceptor<Input>,
{
fn dyn_accept(&self, input: Input) -> AcceptFuture {
let acceptor = self.clone();
Box::pin(async move {
acceptor
.accept(input)
.await
.map(|transport| Box::new(transport) as BoxedTransport)
.map_err(|e| BoxedAcceptError(format!("{e:?}")))
})
}
fn is_secure(&self) -> bool {
Acceptor::is_secure(self)
}
}
pub struct BoxedAcceptor<Input>(Arc<dyn DynAcceptor<Input>>);
impl<Input: Transport> BoxedAcceptor<Input> {
pub fn new<A: Acceptor<Input>>(acceptor: A) -> Self {
Self(Arc::new(acceptor))
}
}
impl<Input: Transport> Clone for BoxedAcceptor<Input> {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}
impl<Input: Transport> Debug for BoxedAcceptor<Input> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("BoxedAcceptor")
.field("is_secure", &self.0.is_secure())
.finish_non_exhaustive()
}
}
impl<Input: Transport> Acceptor<Input> for BoxedAcceptor<Input> {
type Error = BoxedAcceptError;
type Output = BoxedTransport;
async fn accept(&self, input: Input) -> Result<Self::Output, Self::Error> {
self.0.dyn_accept(input).await
}
fn is_secure(&self) -> bool {
self.0.is_secure()
}
}