ppaass_v3_protocol/common/
mod.rs

1use crate::ProtocolError;
2use serde::{Deserialize, Serialize};
3use std::fmt::{Display, Formatter};
4use std::net::{SocketAddr, ToSocketAddrs};
5const HTTP_PORT: u16 = 80;
6
7/// The unified address which can support both
8/// IP V4, IP V6 and Domain
9#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
10pub enum UnifiedAddress {
11    Domain { host: String, port: u16 },
12    SocketAddress(SocketAddr),
13}
14impl Display for UnifiedAddress {
15    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
16        match self {
17            UnifiedAddress::Domain { host, port } => write!(f, "{}:{}", host, port),
18            UnifiedAddress::SocketAddress(socket_addr) => match socket_addr {
19                SocketAddr::V4(ip_v4_addr) => {
20                    write!(f, "{}:{}", ip_v4_addr.ip(), socket_addr.port())
21                }
22                SocketAddr::V6(ip_v6_addr) => {
23                    write!(f, "{}:{}", ip_v6_addr.ip(), socket_addr.port())
24                }
25            },
26        }
27    }
28}
29
30impl TryFrom<&str> for UnifiedAddress {
31    type Error = ProtocolError;
32    fn try_from(value: &str) -> Result<Self, Self::Error> {
33        value.to_string().try_into()
34    }
35}
36
37impl TryFrom<String> for UnifiedAddress {
38    type Error = ProtocolError;
39    fn try_from(value: String) -> Result<Self, Self::Error> {
40        if let Ok(ip_address) = value.parse::<SocketAddr>() {
41            Ok(Self::SocketAddress(ip_address))
42        } else {
43            let domain_parts = value.split(":").collect::<Vec<&str>>();
44            match domain_parts.len() {
45                parts_num if parts_num > 2 => {
46                    Err(ProtocolError::ParseUnifiedAddressToDomainAddress(value))
47                }
48                2 => {
49                    let domain = domain_parts[0];
50                    let port = domain_parts[1].parse::<u16>().map_err(|_| {
51                        ProtocolError::ParseUnifiedAddressToDomainAddress(value.clone())
52                    })?;
53                    Ok(Self::Domain {
54                        host: domain.to_string(),
55                        port,
56                    })
57                }
58                _ => {
59                    let domain = domain_parts[0];
60                    Ok(Self::Domain {
61                        host: domain.to_string(),
62                        port: HTTP_PORT,
63                    })
64                }
65            }
66        }
67    }
68}
69impl TryFrom<UnifiedAddress> for Vec<SocketAddr> {
70    type Error = ProtocolError;
71    fn try_from(value: UnifiedAddress) -> Result<Self, Self::Error> {
72        (&value).try_into()
73    }
74}
75
76impl TryFrom<&UnifiedAddress> for Vec<SocketAddr> {
77    type Error = ProtocolError;
78    fn try_from(value: &UnifiedAddress) -> Result<Self, Self::Error> {
79        match value {
80            UnifiedAddress::Domain { host, port } => {
81                let socket_addresses = format!("{host}:{port}").to_socket_addrs()?;
82                let socket_addresses = socket_addresses.collect::<Vec<SocketAddr>>();
83                Ok(socket_addresses)
84            }
85            UnifiedAddress::SocketAddress(socket_addr) => Ok(vec![*socket_addr]),
86        }
87    }
88}
89impl From<SocketAddr> for UnifiedAddress {
90    fn from(value: SocketAddr) -> Self {
91        UnifiedAddress::SocketAddress(value)
92    }
93}
94
95impl From<&SocketAddr> for UnifiedAddress {
96    fn from(value: &SocketAddr) -> Self {
97        UnifiedAddress::SocketAddress(*value)
98    }
99}