vt_muxer/
thin_addr.rs

1use std::fmt::{Debug, Display, Formatter};
2use std::hash::{Hash, Hasher};
3use std::net::Ipv6Addr;
4use std::str::FromStr;
5use bytemuck::{Pod, Zeroable};
6use crate::integers::NetworkOrderU16;
7
8#[derive(Copy, Clone, Pod, Zeroable, Ord, PartialOrd, Eq, PartialEq)]
9#[repr(C, packed)]
10pub struct IpAddr {
11    octets: [u8; 16]
12}
13
14impl IpAddr {
15    pub const fn to_std(self) -> std::net::IpAddr {
16        Ipv6Addr::from_bits(u128::from_be_bytes(self.octets)).to_canonical()
17    }
18
19    pub const fn from_std(ip: std::net::IpAddr) -> Self {
20        let v6 = match ip {
21            std::net::IpAddr::V4(v4) => v4.to_ipv6_mapped(),
22            std::net::IpAddr::V6(v6) => v6,
23        };
24
25        Self { octets: v6.octets() }
26    }
27}
28
29
30#[derive(Copy, Clone, Pod, Zeroable, Ord, PartialOrd, Eq, PartialEq)]
31#[repr(C, packed)]
32pub struct SocketAddr {
33    ip: IpAddr,
34    port: NetworkOrderU16
35}
36
37impl SocketAddr {
38    pub const fn to_std(self) -> std::net::SocketAddr {
39        std::net::SocketAddr::new(
40            self.ip.to_std(),
41            self.port.get()
42        )
43    }
44
45    pub const fn from_std(sock: std::net::SocketAddr) -> Self {
46        Self {
47            ip: IpAddr::from_std(sock.ip()),
48            port: NetworkOrderU16::new(sock.port())
49        }
50    }
51
52    pub const fn ip(&self) -> IpAddr {
53        self.ip
54    }
55
56    pub const fn port(&self) -> u16 {
57        self.port.get()
58    }
59}
60
61macro_rules! impl_display_debug {
62    ($($type:ty),+) => {$(
63        impl Display for $type {
64            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
65                Display::fmt(&self.to_std(), f)
66            }
67        }
68        
69        impl Debug for $type {
70            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
71                Debug::fmt(&self.to_std(), f)
72            }
73        }
74    )+};
75}
76
77impl_display_debug!(IpAddr, SocketAddr);
78
79macro_rules! impl_byte_hash {
80    ($($type:ty),+) => {$(
81        impl Hash for $type {
82            fn hash<H: Hasher>(&self, state: &mut H) {
83                state.write(bytemuck::bytes_of(self))
84            }
85        
86            fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
87            where
88                Self: Sized,
89            {
90                state.write(bytemuck::cast_slice(data))
91            }
92        }
93    )+};
94}
95
96impl_byte_hash!(IpAddr, SocketAddr);
97
98macro_rules! impl_from_str {
99    ($($ty:ident),+) => {$(
100        impl FromStr for $ty {
101            type Err = <std::net::$ty as FromStr>::Err;
102            
103            fn from_str(s: &str) -> Result<Self, Self::Err> {
104                s.parse().map(Self::from_std)
105            }
106        }
107    )*};
108}
109
110impl_from_str!(IpAddr, SocketAddr);