1use std::{io, path::Path};
2
3use hyper::server::{Builder, Server};
4
5use conn::SocketIncoming;
6
7pub(crate) mod conn {
8 use futures_util::stream::Stream;
9 use hyper::server::accept::Accept;
10 use pin_project::pin_project;
11 use std::{
12 io,
13 path::Path,
14 pin::Pin,
15 task::{Context, Poll},
16 };
17 use tokio::net::{UnixListener, UnixStream};
18
19 #[pin_project]
21 #[derive(Debug)]
22 pub struct SocketIncoming {
23 listener: UnixListener,
24 }
25
26 impl SocketIncoming {
27 pub fn bind(path: impl AsRef<Path>) -> Result<Self, std::io::Error> {
29 let listener = UnixListener::bind(path)?;
30
31 Ok(Self { listener })
32 }
33
34 pub fn from_listener(listener: UnixListener) -> Self {
41 Self { listener }
42 }
43 }
44
45 impl Accept for SocketIncoming {
46 type Conn = UnixStream;
47 type Error = io::Error;
48
49 fn poll_accept(
50 self: Pin<&mut Self>,
51 cx: &mut Context<'_>,
52 ) -> Poll<Option<Result<Self::Conn, Self::Error>>> {
53 let listener = self.project().listener;
54 let mut incoming = listener.incoming();
55 Pin::new(&mut incoming).poll_next(cx)
56 }
57 }
58
59 impl From<UnixListener> for SocketIncoming {
60 fn from(listener: UnixListener) -> Self {
61 Self::from_listener(listener)
62 }
63 }
64}
65
66pub trait UnixServerExt {
87 fn bind_unix(path: impl AsRef<Path>) -> Result<Builder<SocketIncoming>, io::Error>;
89}
90
91impl UnixServerExt for Server<SocketIncoming, ()> {
92 fn bind_unix(path: impl AsRef<Path>) -> Result<Builder<SocketIncoming>, io::Error> {
93 let incoming = SocketIncoming::bind(path)?;
94 Ok(Server::builder(incoming))
95 }
96}