unicom_unix/
lib.rs

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/// Unix socket backend
14///
15/// Support connecting to devices using unix domain sockets
16#[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}