cloudpub_common/unix_tcp/
socket_addr.rs1use std::fmt::{self, Debug, Display, Formatter};
8use std::io;
9use std::net::{self, AddrParseError};
10use std::str::FromStr;
11use std::path::PathBuf;
14
15#[cfg(unix)]
16use tokio::net::unix;
17
18#[cfg(feature = "serde")]
19use serde::{de::Error, Deserialize, Deserializer, Serialize};
20
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
25pub enum UnixSocketAddr {
26 #[cfg(unix)]
27 AbstractOrUnnamed,
28 #[cfg(unix)]
29 Pathname(PathBuf),
30}
31
32#[cfg(unix)]
33impl UnixSocketAddr {
34 pub fn is_pathname(input: &str) -> bool {
35 input.starts_with('/') || input.starts_with('.')
36 }
37}
38
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
41pub enum SocketAddr {
42 Inet(net::SocketAddr),
43 #[cfg(unix)]
44 Unix(UnixSocketAddr),
45}
46
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
49pub enum NamedSocketAddr {
50 Inet(net::SocketAddr),
51 #[cfg(unix)]
52 Unix(PathBuf),
53}
54
55impl SocketAddr {
56 pub fn map_inet<F: FnOnce(net::SocketAddr) -> net::SocketAddr>(self, mapper: F) -> SocketAddr {
57 match self {
58 SocketAddr::Inet(inet_socket_addr) => SocketAddr::Inet(mapper(inet_socket_addr)),
59 #[cfg(unix)]
60 SocketAddr::Unix(unix_socket_addr) => SocketAddr::Unix(unix_socket_addr),
61 }
62 }
63
64 #[cfg_attr(not(unix), allow(unused_variables))]
66 pub fn map_unix<F: FnOnce(UnixSocketAddr) -> UnixSocketAddr>(self, mapper: F) -> SocketAddr {
67 match self {
68 SocketAddr::Inet(inet_socket_addr) => SocketAddr::Inet(inet_socket_addr),
69 #[cfg(unix)]
70 SocketAddr::Unix(unix_socket_addr) => SocketAddr::Unix(mapper(unix_socket_addr)),
71 }
72 }
73
74 pub fn to_named_socket_addr(self) -> io::Result<NamedSocketAddr> {
75 match self {
76 SocketAddr::Inet(inet_socket_addr) => Ok(NamedSocketAddr::Inet(inet_socket_addr)),
77 #[cfg(unix)]
78 SocketAddr::Unix(UnixSocketAddr::Pathname(pathname)) => {
79 Ok(NamedSocketAddr::Unix(pathname))
80 }
81 #[cfg(unix)]
82 SocketAddr::Unix(UnixSocketAddr::AbstractOrUnnamed) => Err(io::Error::new(
83 io::ErrorKind::Unsupported,
84 "Cannot connect to a abstract or unnamed unix socket.",
85 )),
86 }
87 }
88
89 #[cfg_attr(feature = "serde", allow(unused))]
90 #[cfg(feature = "serde")]
91 pub fn deserialize_from_str<'de, D>(deserializer: D) -> Result<SocketAddr, D::Error>
92 where
93 D: Deserializer<'de>,
94 {
95 let string = String::deserialize(deserializer)?;
96 FromStr::from_str(&string).map_err(Error::custom)
97 }
98
99 #[cfg_attr(feature = "serde", allow(unused))]
100 #[cfg(feature = "serde")]
101 pub fn deserialize_from_option_str<'de, D>(
102 deserializer: D,
103 ) -> Result<Option<SocketAddr>, D::Error>
104 where
105 D: Deserializer<'de>,
106 {
107 #[derive(Deserialize)]
108 struct Helper(#[serde(deserialize_with = "SocketAddr::deserialize_from_str")] SocketAddr);
109
110 let option = Option::deserialize(deserializer)?;
111 Ok(option.map(|Helper(external)| external))
112 }
113}
114
115impl NamedSocketAddr {
116 pub fn map_inet<F: FnOnce(net::SocketAddr) -> net::SocketAddr>(
117 self,
118 mapper: F,
119 ) -> NamedSocketAddr {
120 match self {
121 NamedSocketAddr::Inet(inet_socket_addr) => {
122 NamedSocketAddr::Inet(mapper(inet_socket_addr))
123 }
124 #[cfg(unix)]
125 NamedSocketAddr::Unix(path) => NamedSocketAddr::Unix(path),
126 }
127 }
128
129 #[cfg_attr(not(unix), allow(unused_variables))]
131 pub fn map_unix<F: FnOnce(PathBuf) -> PathBuf>(self, mapper: F) -> NamedSocketAddr {
132 match self {
133 NamedSocketAddr::Inet(inet_socket_addr) => NamedSocketAddr::Inet(inet_socket_addr),
134 #[cfg(unix)]
135 NamedSocketAddr::Unix(path) => NamedSocketAddr::Unix(mapper(path)),
136 }
137 }
138
139 pub fn to_socket_addr(self) -> SocketAddr {
140 match self {
141 NamedSocketAddr::Inet(inet_socket_addr) => SocketAddr::Inet(inet_socket_addr),
142 #[cfg(unix)]
143 NamedSocketAddr::Unix(path) => SocketAddr::Unix(UnixSocketAddr::Pathname(path)),
144 }
145 }
146
147 #[cfg_attr(feature = "serde", allow(unused))]
148 #[cfg(feature = "serde")]
149 pub fn deserialize_from_str<'de, D>(deserializer: D) -> Result<NamedSocketAddr, D::Error>
150 where
151 D: Deserializer<'de>,
152 {
153 let string = String::deserialize(deserializer)?;
154 FromStr::from_str(&string).map_err(Error::custom)
155 }
156
157 #[cfg_attr(feature = "serde", allow(unused))]
158 #[cfg(feature = "serde")]
159 pub fn deserialize_from_option_str<'de, D>(
160 deserializer: D,
161 ) -> Result<Option<NamedSocketAddr>, D::Error>
162 where
163 D: Deserializer<'de>,
164 {
165 #[derive(Deserialize)]
166 struct Helper(
167 #[serde(deserialize_with = "NamedSocketAddr::deserialize_from_str")] NamedSocketAddr,
168 );
169
170 let option = Option::deserialize(deserializer)?;
171 Ok(option.map(|Helper(external)| external))
172 }
173}
174
175impl FromStr for SocketAddr {
176 type Err = AddrParseError;
177
178 fn from_str(string: &str) -> Result<Self, Self::Err> {
179 NamedSocketAddr::from_str(string).map(NamedSocketAddr::into)
180 }
181}
182
183impl FromStr for NamedSocketAddr {
184 type Err = AddrParseError;
185
186 fn from_str(string: &str) -> Result<Self, Self::Err> {
187 #[cfg(unix)]
188 if UnixSocketAddr::is_pathname(string) {
189 return Ok(NamedSocketAddr::Unix(PathBuf::from_str(string).unwrap()));
190 }
191
192 Ok(NamedSocketAddr::Inet(net::SocketAddr::from_str(string)?))
193 }
194}
195
196impl From<NamedSocketAddr> for SocketAddr {
197 fn from(named_socket_addr: NamedSocketAddr) -> Self {
198 named_socket_addr.to_socket_addr()
199 }
200}
201
202impl TryFrom<SocketAddr> for NamedSocketAddr {
203 type Error = io::Error;
204
205 fn try_from(socket_addr: SocketAddr) -> Result<Self, Self::Error> {
206 socket_addr.to_named_socket_addr()
207 }
208}
209
210impl From<net::SocketAddr> for SocketAddr {
211 fn from(inet_socket_addr: net::SocketAddr) -> SocketAddr {
212 SocketAddr::Inet(inet_socket_addr)
213 }
214}
215
216impl From<net::SocketAddr> for NamedSocketAddr {
217 fn from(inet_socket_addr: net::SocketAddr) -> NamedSocketAddr {
218 NamedSocketAddr::Inet(inet_socket_addr)
219 }
220}
221
222#[cfg(unix)]
223impl From<PathBuf> for SocketAddr {
224 fn from(path: PathBuf) -> SocketAddr {
225 SocketAddr::Unix(UnixSocketAddr::Pathname(path))
226 }
227}
228
229#[cfg(unix)]
230impl From<PathBuf> for NamedSocketAddr {
231 fn from(path: PathBuf) -> NamedSocketAddr {
232 NamedSocketAddr::Unix(path)
233 }
234}
235
236#[cfg(unix)]
237impl From<UnixSocketAddr> for SocketAddr {
238 fn from(unix_socket_addr: UnixSocketAddr) -> SocketAddr {
239 SocketAddr::Unix(unix_socket_addr)
240 }
241}
242
243#[cfg(unix)]
244impl From<unix::SocketAddr> for SocketAddr {
245 fn from(unix_socket_addr: unix::SocketAddr) -> Self {
246 SocketAddr::Unix(unix_socket_addr.into())
247 }
248}
249
250#[cfg(unix)]
251impl From<unix::SocketAddr> for UnixSocketAddr {
252 fn from(unix_socket_addr: unix::SocketAddr) -> Self {
253 match unix_socket_addr.as_pathname() {
254 Some(path) => UnixSocketAddr::Pathname(path.to_path_buf()),
255 None => UnixSocketAddr::AbstractOrUnnamed,
256 }
257 }
258}
259
260#[cfg(unix)]
261impl Debug for UnixSocketAddr {
262 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
263 match self {
264 UnixSocketAddr::AbstractOrUnnamed => write!(formatter, "(abstract or unnamed)"),
265 UnixSocketAddr::Pathname(path) => write!(formatter, "{path:?} (pathname)"),
266 }
267 }
268}
269
270impl Display for SocketAddr {
271 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
272 match self {
273 SocketAddr::Inet(inet_socket_addr) => write!(formatter, "{}", inet_socket_addr),
274 #[cfg(unix)]
275 SocketAddr::Unix(unix_socket_addr) => write!(formatter, "unix {:?}", unix_socket_addr),
276 }
277 }
278}
279
280impl Display for NamedSocketAddr {
281 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
282 match self {
283 NamedSocketAddr::Inet(inet_socket_addr) => write!(formatter, "{}", inet_socket_addr),
284 #[cfg(unix)]
285 NamedSocketAddr::Unix(path) => write!(formatter, "unix {:?}", path),
286 }
287 }
288}