ppaass_protocol/message/values/
address.rs

1use crate::error::ProtocolError;
2use derive_more::Display;
3use serde_derive::{Deserialize, Serialize};
4use std::net::SocketAddr;
5use std::net::ToSocketAddrs;
6#[derive(Serialize, Deserialize, Debug, Clone, Eq, Display)]
7pub enum UnifiedAddress {
8    #[display("{_0:?}")]
9    Ip(SocketAddr),
10    #[display("{}:{}", host, port)]
11    Domain { host: String, port: u16 },
12}
13
14impl PartialEq for UnifiedAddress {
15    fn eq(&self, other: &Self) -> bool {
16        match self {
17            UnifiedAddress::Ip(ip_addr) => match other {
18                UnifiedAddress::Ip(other_ip_addr) => ip_addr.eq(other_ip_addr),
19                UnifiedAddress::Domain { .. } => false,
20            },
21            UnifiedAddress::Domain { host, port } => match other {
22                UnifiedAddress::Ip(_) => false,
23                UnifiedAddress::Domain {
24                    host: other_host,
25                    port: other_port,
26                } => host == other_host && port == other_port,
27            },
28        }
29    }
30}
31
32pub struct SocketAddrIter {
33    elements: Vec<SocketAddr>,
34    index: usize,
35}
36
37impl SocketAddrIter {
38    pub fn new(elements: Vec<SocketAddr>) -> Self {
39        Self { elements, index: 0 }
40    }
41}
42
43impl Iterator for SocketAddrIter {
44    type Item = SocketAddr;
45
46    fn next(&mut self) -> Option<Self::Item> {
47        let result = self.elements.get(self.index);
48        self.index += 1;
49        result.copied()
50    }
51}
52
53impl ToSocketAddrs for UnifiedAddress {
54    type Iter = SocketAddrIter;
55
56    fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
57        let socket_addr_vec: Vec<SocketAddr> = self
58            .clone()
59            .try_into()
60            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
61        Ok(SocketAddrIter::new(socket_addr_vec))
62    }
63}
64
65impl TryFrom<UnifiedAddress> for Vec<SocketAddr> {
66    type Error = ProtocolError;
67
68    fn try_from(value: UnifiedAddress) -> Result<Self, Self::Error> {
69        match value {
70            UnifiedAddress::Ip(socket_addr) => Ok(vec![socket_addr]),
71            UnifiedAddress::Domain { host, port } => {
72                let address_string = format!("{host}:{port}");
73                let addresses = address_string.to_socket_addrs()?;
74                let addresses = addresses.collect::<Vec<_>>();
75                Ok(addresses)
76            }
77        }
78    }
79}
80
81impl From<SocketAddr> for UnifiedAddress {
82    fn from(value: SocketAddr) -> Self {
83        UnifiedAddress::Ip(value)
84    }
85}