use futures::prelude::*;
use hyper::client::Client;
use hyper::client::connect::{Connection, Connected};
use hyper::http::Uri;
use hyper::service::Service;
use std::future::Future;
use std::ops::{Deref, DerefMut};
use std::path::Path;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncWrite, Result};
use tokio::net::UnixStream;
#[derive(Clone, Debug)]
pub struct UnixSocketConnector(Arc<Path>);
impl UnixSocketConnector {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
let path = Arc::from(path.as_ref());
UnixSocketConnector(path)
}
pub fn connect(&self) -> impl Future<Output=Result<UnixSocketConnection>> {
UnixStream::connect(Arc::clone(&self.0)).map_ok(UnixSocketConnection)
}
pub fn client<P: AsRef<Path>>(path: P) -> Client<Self> {
Client::builder().build(UnixSocketConnector::new(path))
}
}
impl Service<Uri> for UnixSocketConnector{
type Response = UnixSocketConnection;
type Error = tokio::io::Error;
type Future = Pin<Box<UnixSocketFuture>>;
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<()>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, _: Uri) -> Self::Future {
Box::pin(self.connect())
}
}
pub struct UnixSocketConnection(UnixStream);
impl AsyncRead for UnixSocketConnection {
#[inline(always)]
fn poll_read(self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll<Result<usize>> {
Pin::new(&mut self.get_mut().0).poll_read(cx, buf)
}
}
impl AsyncWrite for UnixSocketConnection {
#[inline(always)]
fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8])-> Poll<Result<usize>> {
Pin::new(&mut self.get_mut().0).poll_write(cx, buf)
}
#[inline(always)]
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context)-> Poll<Result<()>> {
Pin::new(&mut self.get_mut().0).poll_flush(cx)
}
#[inline(always)]
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context)-> Poll<Result<()>> {
Pin::new(&mut self.get_mut().0).poll_shutdown(cx)
}
}
impl Connection for UnixSocketConnection {
fn connected(&self) -> Connected {
Connected::new().proxy(true)
}
}
impl Deref for UnixSocketConnection {
type Target = UnixStream;
fn deref(&self) -> &UnixStream {
&self.0
}
}
impl DerefMut for UnixSocketConnection {
fn deref_mut(&mut self) -> &mut UnixStream {
&mut self.0
}
}
type UnixSocketFuture = dyn Future<Output=Result<UnixSocketConnection>> + Send;