aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornetworkException <git@nwex.de>2023-09-29 18:37:36 +0200
committernetworkException <git@nwex.de>2023-09-29 18:37:36 +0200
commit10195f1567e82a630e808bc2700424bce28238c0 (patch)
tree8b548337204a94aa7439e7fdff223c2933f93b49
parent6086a3fa072571c9f2a9903175a9ca36ee497f0d (diff)
downloadgarage-10195f1567e82a630e808bc2700424bce28238c0.tar.gz
garage-10195f1567e82a630e808bc2700424bce28238c0.zip
util: add helper sum type for unix and tcp socket addresses
this patch introduces a new sum type that can represent either a tcp socket address or a unix domain socket path.
-rw-r--r--src/util/lib.rs1
-rw-r--r--src/util/socket_address.rs44
2 files changed, 45 insertions, 0 deletions
diff --git a/src/util/lib.rs b/src/util/lib.rs
index 15f0f829..7df77959 100644
--- a/src/util/lib.rs
+++ b/src/util/lib.rs
@@ -14,6 +14,7 @@ pub mod forwarded_headers;
pub mod metrics;
pub mod migrate;
pub mod persister;
+pub mod socket_address;
pub mod time;
pub mod tranquilizer;
pub mod version;
diff --git a/src/util/socket_address.rs b/src/util/socket_address.rs
new file mode 100644
index 00000000..f01225f6
--- /dev/null
+++ b/src/util/socket_address.rs
@@ -0,0 +1,44 @@
+use std::fmt::{Debug, Display, Formatter};
+use std::net::SocketAddr;
+use std::path::PathBuf;
+use std::str::FromStr;
+
+use serde::de::Error;
+use serde::{Deserialize, Deserializer};
+
+#[derive(Debug, Clone)]
+pub enum UnixOrTCPSocketAddress {
+ TCPSocket(SocketAddr),
+ UnixSocket(PathBuf),
+}
+
+impl Display for UnixOrTCPSocketAddress {
+ fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
+ match self {
+ UnixOrTCPSocketAddress::TCPSocket(address) => write!(formatter, "http://{}", address),
+ UnixOrTCPSocketAddress::UnixSocket(path) => {
+ write!(formatter, "http+unix://{}", path.to_string_lossy())
+ }
+ }
+ }
+}
+
+impl<'de> Deserialize<'de> for UnixOrTCPSocketAddress {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let string = String::deserialize(deserializer)?;
+ let string = string.as_str();
+
+ if string.starts_with("/") {
+ Ok(UnixOrTCPSocketAddress::UnixSocket(
+ PathBuf::from_str(string).map_err(Error::custom)?,
+ ))
+ } else {
+ Ok(UnixOrTCPSocketAddress::TCPSocket(
+ SocketAddr::from_str(string).map_err(Error::custom)?,
+ ))
+ }
+ }
+}