pub mod http_connector;
pub mod https_connector;
#[cfg(any(target_os = "macos", target_family = "unix"))]
pub mod unix_connector;
use hyper::Uri;
use tokio::io::{AsyncRead, AsyncWrite};
use tower::make::MakeConnection;
use tower_service::Service;
use super::io::BoxIO;
use crate::utils::boxed_clone::BoxCloneService;
#[derive(Clone)]
pub struct Connector<C> {
inner: C,
}
impl<C> Connector<C> {
pub fn new(inner: C) -> Connector<C>
where
C: Service<Uri>,
C::Error: Into<crate::Error>,
C::Response: AsyncRead + AsyncWrite + Send + 'static,
{
Self { inner }
}
}
impl<C> Service<Uri> for Connector<C>
where
C: MakeConnection<Uri>,
C::Connection: Unpin + Send + 'static,
C::Future: Send + 'static,
crate::Error: From<C::Error> + Send + 'static,
{
type Response = BoxIO;
type Error = crate::Error;
type Future = crate::BoxFuture<Self::Response, Self::Error>;
fn poll_ready(
&mut self,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), Self::Error>> {
MakeConnection::poll_ready(&mut self.inner, cx).map_err(Into::into)
}
fn call(&mut self, uri: Uri) -> Self::Future {
let conn = self.inner.make_connection(uri);
Box::pin(async move {
let io = conn.await?;
Ok(BoxIO::new(io))
})
}
}
pub fn get_connector(connector: &str) -> BoxCloneService<Uri, BoxIO, crate::Error> {
match connector {
"http" => {
let c = http_connector::HttpConnector::new();
BoxCloneService::new(Connector::new(c))
}
"https" => {
let c = https_connector::HttpsConnector::new();
BoxCloneService::new(Connector::new(c))
}
#[cfg(any(target_os = "macos", target_family = "unix"))]
"unix" => {
let c = unix_connector::UnixConnector::new();
BoxCloneService::new(Connector::new(c))
}
_ => {
let c = http_connector::HttpConnector::new();
BoxCloneService::new(Connector::new(c))
}
}
}