zbus/address/transport/
unix.rs1#[cfg(target_os = "linux")]
2use std::ffi::OsString;
3use std::{
4 ffi::OsStr,
5 fmt::{Display, Formatter},
6 path::PathBuf,
7};
8
9#[cfg(unix)]
10use super::encode_percents;
11
12#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct Unix {
15 path: UnixSocket,
16}
17
18impl Unix {
19 pub fn new(path: UnixSocket) -> Self {
21 Self { path }
22 }
23
24 pub fn path(&self) -> &UnixSocket {
26 &self.path
27 }
28
29 pub fn take_path(self) -> UnixSocket {
31 self.path
32 }
33
34 pub(super) fn from_options(opts: std::collections::HashMap<&str, &str>) -> crate::Result<Self> {
35 let path = opts.get("path");
36 let abs = opts.get("abstract");
37 let dir = opts.get("dir");
38 let tmpdir = opts.get("tmpdir");
39 let path = match (path, abs, dir, tmpdir) {
40 (Some(p), None, None, None) => UnixSocket::File(PathBuf::from(p)),
41 #[cfg(target_os = "linux")]
42 (None, Some(p), None, None) => UnixSocket::Abstract(OsString::from(p)),
43 #[cfg(not(target_os = "linux"))]
44 (None, Some(_), None, None) => {
45 return Err(crate::Error::Address(
46 "abstract sockets currently Linux-only".to_owned(),
47 ));
48 }
49 (None, None, Some(p), None) => UnixSocket::Dir(PathBuf::from(p)),
50 (None, None, None, Some(p)) => UnixSocket::TmpDir(PathBuf::from(p)),
51 _ => {
52 return Err(crate::Error::Address("unix: address is invalid".to_owned()));
53 }
54 };
55
56 Ok(Self::new(path))
57 }
58}
59
60impl Display for Unix {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(f, "unix:{}", self.path)
63 }
64}
65
66#[derive(Clone, Debug, PartialEq, Eq)]
68#[non_exhaustive]
69pub enum UnixSocket {
70 File(PathBuf),
72 #[cfg(target_os = "linux")]
74 Abstract(OsString),
75 Dir(PathBuf),
83 TmpDir(PathBuf),
89}
90
91impl Display for UnixSocket {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 fn fmt_unix_path(f: &mut Formatter<'_>, path: &OsStr) -> std::fmt::Result {
94 #[cfg(unix)]
95 {
96 use std::os::unix::ffi::OsStrExt;
97
98 encode_percents(f, path.as_bytes())?;
99 }
100
101 #[cfg(windows)]
102 write!(f, "{}", path.to_str().ok_or(std::fmt::Error)?)?;
103
104 Ok(())
105 }
106
107 match self {
108 UnixSocket::File(path) => {
109 f.write_str("path=")?;
110 fmt_unix_path(f, path.as_os_str())?;
111 }
112 #[cfg(target_os = "linux")]
113 UnixSocket::Abstract(name) => {
114 f.write_str("abstract=")?;
115 fmt_unix_path(f, name)?;
116 }
117 UnixSocket::Dir(path) => {
118 f.write_str("dir=")?;
119 fmt_unix_path(f, path.as_os_str())?;
120 }
121 UnixSocket::TmpDir(path) => {
122 f.write_str("tmpdir=")?;
123 fmt_unix_path(f, path.as_os_str())?;
124 }
125 }
126
127 Ok(())
128 }
129}