aboutsummaryrefslogtreecommitdiff
path: root/src/util/socket_address.rs
blob: f01225f684633921cb6497566d717de656448360 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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)?,
			))
		}
	}
}