use std::fmt;
use std::marker;
use crate::assert_send;
use crate::assert_sync;
use crate::AsyncSocket;
use crate::AsyncSocketBox;
use crate::BoxFuture;
use crate::ImplInfo;
use crate::TlsAcceptor;
use crate::TlsAcceptorBuilder;
use crate::TlsStream;
pub trait TlsAcceptorType: fmt::Debug + fmt::Display + Sync + 'static {
fn implemented(&self) -> bool;
fn supports_alpn(&self) -> bool;
fn supports_der_keys(&self) -> bool;
fn supports_pkcs12_keys(&self) -> bool;
fn info(&self) -> ImplInfo;
fn builder_from_der_key(
&self,
cert: &[u8],
key: &[u8],
) -> anyhow::Result<TlsAcceptorBuilderBox>;
fn builder_from_pkcs12(
&self,
pkcs12: &[u8],
passphrase: &str,
) -> anyhow::Result<TlsAcceptorBuilderBox>;
}
pub(crate) struct TlsAcceptorTypeImpl<A: TlsAcceptor>(pub marker::PhantomData<A>);
impl<A: TlsAcceptor> fmt::Debug for TlsAcceptorTypeImpl<A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&A::info(), f)
}
}
impl<A: TlsAcceptor> fmt::Display for TlsAcceptorTypeImpl<A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&A::info(), f)
}
}
impl<A: TlsAcceptor> TlsAcceptorType for TlsAcceptorTypeImpl<A> {
fn implemented(&self) -> bool {
A::IMPLEMENTED
}
fn supports_alpn(&self) -> bool {
A::SUPPORTS_ALPN
}
fn supports_der_keys(&self) -> bool {
A::SUPPORTS_DER_KEYS
}
fn supports_pkcs12_keys(&self) -> bool {
A::SUPPORTS_PKCS12_KEYS
}
fn info(&self) -> ImplInfo {
A::info()
}
fn builder_from_der_key(
&self,
cert: &[u8],
key: &[u8],
) -> anyhow::Result<TlsAcceptorBuilderBox> {
let builder = A::builder_from_der_key(cert, key)?;
Ok(TlsAcceptorBuilderBox(Box::new(builder)))
}
fn builder_from_pkcs12(
&self,
pkcs12: &[u8],
passphrase: &str,
) -> anyhow::Result<TlsAcceptorBuilderBox> {
let builder = A::builder_from_pkcs12(pkcs12, passphrase)?;
Ok(TlsAcceptorBuilderBox(Box::new(builder)))
}
}
trait TlsAcceptorBuilderDyn: Send + 'static {
fn type_dyn(&self) -> &'static dyn TlsAcceptorType;
fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> anyhow::Result<()>;
fn build(self: Box<Self>) -> anyhow::Result<TlsAcceptorBox>;
}
impl<A: TlsAcceptorBuilder> TlsAcceptorBuilderDyn for A {
fn type_dyn(&self) -> &'static dyn TlsAcceptorType {
<A::Acceptor as TlsAcceptor>::TYPE_DYN
}
fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> anyhow::Result<()> {
(*self).set_alpn_protocols(protocols)
}
fn build(self: Box<Self>) -> anyhow::Result<TlsAcceptorBox> {
Ok(TlsAcceptorBox(Box::new((*self).build()?)))
}
}
pub struct TlsAcceptorBuilderBox(Box<dyn TlsAcceptorBuilderDyn>);
impl TlsAcceptorBuilderBox {
pub fn type_dyn(&self) -> &'static dyn TlsAcceptorType {
self.0.type_dyn()
}
pub fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> anyhow::Result<()> {
self.0.set_alpn_protocols(protocols)
}
pub fn build(self) -> anyhow::Result<TlsAcceptorBox> {
self.0.build()
}
}
trait TlsAcceptorDyn: Send + Sync + 'static {
fn type_dyn(&self) -> &'static dyn TlsAcceptorType;
fn accept(&self, socket: AsyncSocketBox) -> BoxFuture<'_, anyhow::Result<TlsStream>>;
}
impl<A: TlsAcceptor> TlsAcceptorDyn for A {
fn type_dyn(&self) -> &'static dyn TlsAcceptorType {
A::TYPE_DYN
}
fn accept(&self, socket: AsyncSocketBox) -> BoxFuture<'_, anyhow::Result<TlsStream>> {
self.accept(socket)
}
}
pub struct TlsAcceptorBox(Box<dyn TlsAcceptorDyn>);
impl TlsAcceptorBox {
pub(crate) fn new<A: TlsAcceptor>(acceptor: A) -> TlsAcceptorBox {
TlsAcceptorBox(Box::new(acceptor))
}
pub fn type_dyn(&self) -> &'static dyn TlsAcceptorType {
self.0.type_dyn()
}
pub fn accept<S: AsyncSocket>(&self, socket: S) -> BoxFuture<'_, anyhow::Result<TlsStream>> {
self.0.accept(AsyncSocketBox::new(socket))
}
}
fn _assert_kinds() {
assert_send::<TlsAcceptorBuilderBox>();
assert_send::<TlsAcceptorBox>();
assert_sync::<TlsAcceptorBox>();
}