use std::fmt::Debug;
use smol::io::{AsyncRead as Read, AsyncWrite as Write};
use smol::net::TcpStream;
#[cfg(feature = "smol-async-native-tls")]
mod native_tls;
#[cfg(feature = "smol-async-native-tls")]
pub use self::native_tls::{AsyncNativeTlsConnector, AsyncNativeTlsStream};
#[cfg(any(feature = "smol-rustls-aws-lc-rs", feature = "smol-rustls-ring"))]
mod rustls;
#[cfg(any(feature = "smol-rustls-aws-lc-rs", feature = "smol-rustls-ring"))]
pub use self::rustls::{AsyncRustlsConnector, AsyncRustlsStream};
#[cfg(feature = "async-secure")]
#[async_trait::async_trait]
pub trait AsyncTlsConnector: Debug {
type Stream: SmolTlsStream;
async fn connect(&self, domain: &str, stream: TcpStream) -> crate::FtpResult<Self::Stream>;
}
pub trait SmolTlsStream: Debug + Read + Write + Unpin {
type InnerStream: Read + Write;
fn tcp_stream(self) -> crate::FtpResult<TcpStream>;
fn get_ref(&self) -> &TcpStream;
fn mut_ref(&mut self) -> &mut Self::InnerStream;
}
#[derive(Debug)]
pub struct AsyncNoTlsStream;
fn no_tls_stream_error() -> std::io::Error {
std::io::Error::new(
std::io::ErrorKind::Unsupported,
"AsyncNoTlsStream is a placeholder for plain FTP and cannot perform TLS I/O",
)
}
impl Read for AsyncNoTlsStream {
fn poll_read(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
_buf: &mut [u8],
) -> std::task::Poll<std::io::Result<usize>> {
std::task::Poll::Ready(Err(no_tls_stream_error()))
}
}
impl Write for AsyncNoTlsStream {
fn poll_write(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
_buf: &[u8],
) -> std::task::Poll<std::io::Result<usize>> {
std::task::Poll::Ready(Err(no_tls_stream_error()))
}
fn poll_flush(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> std::task::Poll<std::io::Result<()>> {
std::task::Poll::Ready(Err(no_tls_stream_error()))
}
fn poll_close(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> std::task::Poll<std::io::Result<()>> {
std::task::Poll::Ready(Err(no_tls_stream_error()))
}
}
impl SmolTlsStream for AsyncNoTlsStream {
type InnerStream = TcpStream;
fn tcp_stream(self) -> crate::FtpResult<TcpStream> {
unreachable!(
"AsyncNoTlsStream is a placeholder for plain FTP and has no underlying TcpStream"
)
}
fn get_ref(&self) -> &TcpStream {
unreachable!(
"AsyncNoTlsStream is a placeholder for plain FTP and has no underlying TcpStream"
)
}
fn mut_ref(&mut self) -> &mut Self::InnerStream {
unreachable!(
"AsyncNoTlsStream is a placeholder for plain FTP and has no underlying TcpStream"
)
}
}