use crate::connector::{NetworkConnection, NetworkConnector};
use hyper::client::connect::Connection;
use hyper::service::Service;
use hyper::Uri;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::sync::Mutex;
use std::error::Error as StdError;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
pub struct HyperConnectorAdapter<T>(Arc<Mutex<T>>);
impl<T> HyperConnectorAdapter<T> {
pub fn new(inner: T) -> Self {
HyperConnectorAdapter(Arc::new(Mutex::new(inner)))
}
}
impl<S, T> NetworkConnector for HyperConnectorAdapter<S>
where
S: Service<Uri, Response = T> + Send + 'static,
S::Error: Into<Box<dyn StdError + Send + Sync>>,
S::Future: Unpin + Send,
T: AsyncRead + AsyncWrite + Connection + Unpin + Send + 'static,
{
fn connect(
&self,
uri: Uri,
) -> Pin<
Box<dyn Future<Output = Result<NetworkConnection, Box<dyn StdError + Send + Sync>>> + Send>,
> {
let inner = self.0.clone();
Box::pin(async move {
match inner.lock().await.call(uri).await {
Ok(conn) => Ok(NetworkConnection::new(conn)),
Err(e) => Err(e.into()),
}
})
}
}