hyper_unix_socket/
client.rs1use std::fmt;
2use std::future::Future;
3use std::marker::PhantomData;
4use std::path::Path;
5use std::pin::Pin;
6use std::task::{self, Context, Poll};
7
8use hyper::Uri;
9use hyper_util::rt::TokioIo;
10use pin_project_lite::pin_project;
11use tokio::net::UnixStream;
12use tower_service::Service;
13
14use super::UnixSocketConnection;
15
16type BoxError = Box<dyn std::error::Error + Send + Sync>;
17
18#[derive(Clone)]
20pub struct UnixSocketConnector<P> {
21 socket_path: P,
22}
23
24impl<P: AsRef<Path>> UnixSocketConnector<P> {
25 #[must_use]
27 pub fn new(socket_path: P) -> Self {
28 Self { socket_path }
29 }
30}
31
32impl<T: AsRef<Path>> From<T> for UnixSocketConnector<T> {
33 fn from(args: T) -> UnixSocketConnector<T> {
34 UnixSocketConnector { socket_path: args }
35 }
36}
37
38impl<T> fmt::Debug for UnixSocketConnector<T> {
39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40 f.debug_struct("HttpsConnector").finish_non_exhaustive()
41 }
42}
43
44impl<T> Service<Uri> for UnixSocketConnector<T>
45where
46 T: AsRef<Path> + Clone + Send,
47{
48 type Response = UnixSocketConnection;
49 type Error = BoxError;
50 type Future = UnixStreamConnecting;
51
52 fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
53 Poll::Ready(Ok(()))
54 }
55
56 fn call(&mut self, _: Uri) -> Self::Future {
57 let socket_path = self.socket_path.as_ref().to_owned();
58
59 let fut = async move {
60 UnixStream::connect(socket_path)
61 .await
62 .map(TokioIo::new)
63 .map(Into::into)
64 .map_err(Into::into)
65 };
66
67 UnixStreamConnecting {
68 fut: Box::pin(fut),
69 _marker: PhantomData,
70 }
71 }
72}
73
74type ConnectResult = Result<UnixSocketConnection, BoxError>;
75type BoxConnecting = Pin<Box<dyn Future<Output = ConnectResult> + Send>>;
76
77pin_project! {
78 #[must_use = "futures do nothing unless polled"]
79 #[allow(missing_debug_implementations)]
80 pub struct UnixStreamConnecting<R = ()> {
81 #[pin]
82 fut: BoxConnecting,
83 _marker: PhantomData<R>,
84 }
85}
86
87impl<R> Future for UnixStreamConnecting<R> {
88 type Output = ConnectResult;
89
90 fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
91 self.project().fut.poll(cx)
92 }
93}
94
95impl<R> fmt::Debug for UnixStreamConnecting<R> {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 f.pad("UnixStreamConnecting")
98 }
99}