1#![doc = include_str!("../README.md")]
2
3use std::{path::PathBuf, sync::Arc};
4
5#[cfg(feature = "tokio")]
6use tokio::net::UnixStream;
7
8#[cfg(feature = "async")]
9use async_net::unix::UnixStream;
10
11use unicom::{Backend, BoxedConnect, BoxedConnection, BoxedConnector, Connector, Error, Url};
12
13#[derive(Clone)]
17pub struct UnixSocket {
18 name: String,
19 description: String,
20}
21
22impl Default for UnixSocket {
23 fn default() -> Self {
24 Self {
25 name: "unix-socket".into(),
26 description: "Support for local unix domain socket connections.".into(),
27 }
28 }
29}
30
31impl Backend for UnixSocket {
32 fn name(&self) -> &str {
33 &self.name
34 }
35
36 fn description(&self) -> &str {
37 &self.description
38 }
39
40 fn connector(&self, url: &Url) -> Option<BoxedConnector> {
41 if (url.scheme() == "socket" || url.scheme() == "unix")
42 && !url.has_host()
43 && url.path() != "/"
44 {
45 let path = url.path().into();
46 let url = url.clone();
47 Some(Arc::new(UnixConnector { url, path }))
48 } else {
49 None
50 }
51 }
52}
53
54#[derive(Clone)]
55struct UnixConnector {
56 url: Url,
57 path: PathBuf,
58}
59
60impl Connector for UnixConnector {
61 fn url(&self) -> &Url {
62 &self.url
63 }
64
65 fn connect(&self) -> BoxedConnect {
66 let this = self.clone();
67 Box::pin(async move {
68 let stm = UnixStream::connect(this.path)
69 .await
70 .map_err(|e| Error::FailedConnect(e.to_string()))?;
71 Ok(Box::new(stm) as BoxedConnection)
72 })
73 }
74}