1use std::io;
8use std::fmt::{self, Debug, Display, Formatter};
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::{Serialize, Deserialize, Deserializer, de::Error};
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)) => Ok(NamedSocketAddr::Unix(pathname)),
79 #[cfg(unix)]
80 SocketAddr::Unix(UnixSocketAddr::AbstractOrUnnamed) => Err(io::Error::new(
81 io::ErrorKind::Unsupported,
82 "Cannot connect to a abstract or unnamed unix socket.",
83 ))
84 }
85 }
86
87 #[cfg_attr(feature = "serde", allow(unused))]
88 #[cfg(feature = "serde")]
89 pub fn deserialize_from_str<'de, D>(deserializer: D) -> Result<SocketAddr, D::Error>
90 where
91 D: Deserializer<'de>,
92 {
93 let string = String::deserialize(deserializer)?;
94 FromStr::from_str(&string).map_err(Error::custom)
95 }
96
97 #[cfg_attr(feature = "serde", allow(unused))]
98 #[cfg(feature = "serde")]
99 pub fn deserialize_from_option_str<'de, D>(deserializer: D) -> Result<Option<SocketAddr>, D::Error>
100 where
101 D: Deserializer<'de>,
102 {
103 #[derive(Deserialize)]
104 struct Helper(#[serde(deserialize_with = "SocketAddr::deserialize_from_str")] SocketAddr);
105
106 let option = Option::deserialize(deserializer)?;
107 Ok(option.map(|Helper(external)| external))
108 }
109}
110
111impl NamedSocketAddr {
112 pub fn map_inet<F: FnOnce(net::SocketAddr) -> net::SocketAddr>(self, mapper: F) -> NamedSocketAddr {
113 match self {
114 NamedSocketAddr::Inet(inet_socket_addr) => NamedSocketAddr::Inet(mapper(inet_socket_addr)),
115 #[cfg(unix)]
116 NamedSocketAddr::Unix(path) => NamedSocketAddr::Unix(path),
117 }
118 }
119
120 #[cfg_attr(not(unix), allow(unused_variables))]
122 pub fn map_unix<F: FnOnce(PathBuf) -> PathBuf>(self, mapper: F) -> NamedSocketAddr {
123 match self {
124 NamedSocketAddr::Inet(inet_socket_addr) => NamedSocketAddr::Inet(inet_socket_addr),
125 #[cfg(unix)]
126 NamedSocketAddr::Unix(path) => NamedSocketAddr::Unix(mapper(path)),
127 }
128 }
129
130 pub fn to_socket_addr(self) -> SocketAddr {
131 match self {
132 NamedSocketAddr::Inet(inet_socket_addr) => SocketAddr::Inet(inet_socket_addr),
133 #[cfg(unix)]
134 NamedSocketAddr::Unix(path) => SocketAddr::Unix(UnixSocketAddr::Pathname(path)),
135 }
136 }
137
138 #[cfg_attr(feature = "serde", allow(unused))]
139 #[cfg(feature = "serde")]
140 pub fn deserialize_from_str<'de, D>(deserializer: D) -> Result<NamedSocketAddr, D::Error>
141 where
142 D: Deserializer<'de>,
143 {
144 let string = String::deserialize(deserializer)?;
145 FromStr::from_str(&string).map_err(Error::custom)
146 }
147
148 #[cfg_attr(feature = "serde", allow(unused))]
149 #[cfg(feature = "serde")]
150 pub fn deserialize_from_option_str<'de, D>(deserializer: D) -> Result<Option<NamedSocketAddr>, D::Error>
151 where
152 D: Deserializer<'de>,
153 {
154 #[derive(Deserialize)]
155 struct Helper(#[serde(deserialize_with = "NamedSocketAddr::deserialize_from_str")] NamedSocketAddr);
156
157 let option = Option::deserialize(deserializer)?;
158 Ok(option.map(|Helper(external)| external))
159 }
160}
161
162impl FromStr for SocketAddr {
163 type Err = AddrParseError;
164
165 fn from_str(string: &str) -> Result<Self, Self::Err> {
166 NamedSocketAddr::from_str(string).map(NamedSocketAddr::into)
167 }
168}
169
170impl FromStr for NamedSocketAddr {
171 type Err = AddrParseError;
172
173 fn from_str(string: &str) -> Result<Self, Self::Err> {
174 #[cfg(unix)]
175 if UnixSocketAddr::is_pathname(string) {
176 return Ok(NamedSocketAddr::Unix(PathBuf::from_str(string).unwrap()))
177 }
178
179 Ok(NamedSocketAddr::Inet(net::SocketAddr::from_str(string)?))
180 }
181}
182
183impl From<NamedSocketAddr> for SocketAddr {
184 fn from(named_socket_addr: NamedSocketAddr) -> Self {
185 named_socket_addr.to_socket_addr()
186 }
187}
188
189impl TryFrom<SocketAddr> for NamedSocketAddr {
190 type Error = io::Error;
191
192 fn try_from(socket_addr: SocketAddr) -> Result<Self, Self::Error> {
193 socket_addr.to_named_socket_addr()
194 }
195}
196
197impl From<net::SocketAddr> for SocketAddr {
198 fn from(inet_socket_addr: net::SocketAddr) -> SocketAddr {
199 SocketAddr::Inet(inet_socket_addr)
200 }
201}
202
203impl From<net::SocketAddr> for NamedSocketAddr {
204 fn from(inet_socket_addr: net::SocketAddr) -> NamedSocketAddr {
205 NamedSocketAddr::Inet(inet_socket_addr)
206 }
207}
208
209#[cfg(unix)]
210impl From<PathBuf> for SocketAddr {
211 fn from(path: PathBuf) -> SocketAddr {
212 SocketAddr::Unix(UnixSocketAddr::Pathname(path))
213 }
214}
215
216#[cfg(unix)]
217impl From<PathBuf> for NamedSocketAddr {
218 fn from(path: PathBuf) -> NamedSocketAddr {
219 NamedSocketAddr::Unix(path)
220 }
221}
222
223#[cfg(unix)]
224impl From<UnixSocketAddr> for SocketAddr {
225 fn from(unix_socket_addr: UnixSocketAddr) -> SocketAddr {
226 SocketAddr::Unix(unix_socket_addr)
227 }
228}
229
230#[cfg(unix)]
231impl From<unix::SocketAddr> for SocketAddr {
232 fn from(unix_socket_addr: unix::SocketAddr) -> Self {
233 SocketAddr::Unix(unix_socket_addr.into())
234 }
235}
236
237#[cfg(unix)]
238impl From<unix::SocketAddr> for UnixSocketAddr {
239 fn from(unix_socket_addr: unix::SocketAddr) -> Self {
240 match unix_socket_addr.as_pathname() {
241 Some(path) => UnixSocketAddr::Pathname(path.to_path_buf()),
242 None => UnixSocketAddr::AbstractOrUnnamed,
243 }
244 }
245}
246
247#[cfg(unix)]
248impl Debug for UnixSocketAddr {
249 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
250 match self {
251 UnixSocketAddr::AbstractOrUnnamed => write!(formatter, "(abstract or unnamed)"),
252 UnixSocketAddr::Pathname(path) => write!(formatter, "{path:?} (pathname)"),
253 }
254 }
255}
256
257impl Display for SocketAddr {
258 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
259 match self {
260 SocketAddr::Inet(inet_socket_addr) => write!(formatter, "{}", inet_socket_addr),
261 #[cfg(unix)]
262 SocketAddr::Unix(unix_socket_addr) => write!(formatter, "unix {:?}", unix_socket_addr),
263 }
264 }
265}
266
267impl Display for NamedSocketAddr {
268 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
269 match self {
270 NamedSocketAddr::Inet(inet_socket_addr) => write!(formatter, "{}", inet_socket_addr),
271 #[cfg(unix)]
272 NamedSocketAddr::Unix(path) => write!(formatter, "unix {:?}", path),
273 }
274 }
275}