btp 0.1.0

A rust library of, a lightweight protocol, Blog Transfer Protocol.
Documentation
use super::socket::{BtpConfig, BtpSocket};
use std::future::Future;
use std::net::SocketAddr;
use tokio::net::{TcpListener, TcpStream};

#[cfg(feature = "tls")]
use std::sync::Arc;

type Error = Box<dyn std::error::Error + Send + Sync>;

pub trait AsListener {
    fn accept(&self) -> impl Future<Output = Result<(TcpStream, SocketAddr), std::io::Error>>;
}

pub struct BtpListener<Listener: AsListener> {
    pub listener: Listener,
    pub btp_conf: BtpConfig,
    #[cfg(feature = "tls")]
    pub tls_conf: Arc<rustls::ServerConfig>,
}

impl AsListener for TcpListener {
    fn accept(&self) -> impl Future<Output = Result<(TcpStream, SocketAddr), std::io::Error>> {
        return self.accept();
    }
}

#[cfg(not(feature = "tls"))]
mod _impl {

    use super::*;

    impl<L: AsListener> BtpListener<L> {
        pub async fn from(listener: L, btp_conf: BtpConfig) -> Self {
            BtpListener { listener, btp_conf }
        }

        pub async fn accept(&self) -> Result<BtpSocket<TcpStream, std::net::SocketAddr>, Error> {
            let (socket, peer) = self.listener.accept().await?;
            let me = BtpConfig {
                ver: self.btp_conf.ver,
                addr: self.btp_conf.addr,
            };
            Ok(BtpSocket::from(socket, me, peer))
        }
    }
}

#[cfg(feature = "tls")]
mod _impl {
    use crate::VERSION;

    use super::*;
    use rustls::ServerConfig;
    use std::sync::Arc;
    use tokio_rustls::{TlsAcceptor, server::TlsStream};

    impl<L: AsListener> BtpListener<L> {
        pub async fn from(listener: L, btp_conf: BtpConfig, tls_conf: Arc<ServerConfig>) -> Self {
            BtpListener {
                listener,
                btp_conf,
                tls_conf,
            }
        }

        pub async fn accept(
            &self,
        ) -> Result<BtpSocket<TlsStream<TcpStream>, std::net::SocketAddr>, Error> {
            let acceptor = TlsAcceptor::from(self.tls_conf.clone());
            let (socket, peer) = self.listener.accept().await?;

            let tls_stream = acceptor.accept(socket).await?;
            let conf = BtpConfig {
                ver: VERSION,
                addr: peer,
            };
            Ok(BtpSocket::from(tls_stream, conf, peer))
        }
    }
}