1use std::{
2 fmt::{Debug, Display},
3 hash::Hash,
4 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},
5 str::FromStr,
6};
7
8mod sealed {
9 pub trait Sealed {}
10}
11
12pub trait AnyIpFamily
13where
14 Self: sealed::Sealed,
15 Self::Addr: IpFamilyAddr<Family = Self>,
16 Self::SocketAddr: IpFamilySocketAddr<Family = Self>,
17 IpAddr: From<Self::Addr>,
18 SocketAddr: From<Self::SocketAddr>,
19{
20 type Addr;
21 type SocketAddr;
22
23 const FAMILY: IpFamily;
24}
25
26pub trait IpFamilyAddr
27where
28 Self: sealed::Sealed
29 + Copy
30 + Debug
31 + Display
32 + Eq
33 + From<Self::Raw>
34 + From<Self::Bytes>
35 + FromStr
36 + Hash
37 + Ord,
38 Self::Family: AnyIpFamily<Addr = Self>,
39 Self::Raw: From<Self>,
40 IpAddr: From<Self>,
41 SocketAddr: From<<Self::Family as AnyIpFamily>::SocketAddr>,
42{
43 type Family;
44 type Raw;
45 type Bytes;
46
47 const BYTES: usize;
48 const LOCALHOST: Self;
49 const UNSPECIFIED: Self;
50
51 fn octets(&self) -> Self::Bytes;
52 fn is_unspecified(&self) -> bool;
53 fn is_loopback(&self) -> bool;
54 fn is_multicast(&self) -> bool;
55}
56
57pub trait IpFamilySocketAddr
58where
59 Self: sealed::Sealed + Copy + Debug + Display + Eq + FromStr + Hash + Ord + ToSocketAddrs,
60
61 Self::Family: AnyIpFamily<SocketAddr = Self>,
62 IpAddr: From<<Self::Family as AnyIpFamily>::Addr>,
63 SocketAddr: From<Self>,
64{
65 type Family;
66
67 fn new(ip: <Self::Family as AnyIpFamily>::Addr, port: u16) -> Self;
68 fn ip(&self) -> <Self::Family as AnyIpFamily>::Addr;
69 fn set_ip(&mut self, new_ip: <Self::Family as AnyIpFamily>::Addr);
70 fn port(&self) -> u16;
71 fn set_port(&mut self, new_port: u16);
72}
73
74pub struct IpFamilyV4;
75
76impl sealed::Sealed for IpFamilyV4 {}
77impl AnyIpFamily for IpFamilyV4 {
78 type Addr = Ipv4Addr;
79
80 type SocketAddr = SocketAddrV4;
81
82 const FAMILY: IpFamily = IpFamily::V4;
83}
84
85const IPV4_ADDR_BYTES: usize = 4;
86impl sealed::Sealed for Ipv4Addr {}
87impl IpFamilyAddr for Ipv4Addr {
88 type Family = IpFamilyV4;
89 type Raw = u32;
90 type Bytes = [u8; IPV4_ADDR_BYTES];
91
92 const BYTES: usize = IPV4_ADDR_BYTES;
93 const LOCALHOST: Self = Self::LOCALHOST;
94 const UNSPECIFIED: Self = Self::UNSPECIFIED;
95
96 fn octets(&self) -> Self::Bytes {
97 self.octets()
98 }
99
100 fn is_unspecified(&self) -> bool {
101 self.is_unspecified()
102 }
103
104 fn is_loopback(&self) -> bool {
105 self.is_loopback()
106 }
107
108 fn is_multicast(&self) -> bool {
109 self.is_multicast()
110 }
111}
112
113impl sealed::Sealed for SocketAddrV4 {}
114impl IpFamilySocketAddr for SocketAddrV4 {
115 type Family = IpFamilyV4;
116
117 fn new(ip: <Self::Family as AnyIpFamily>::Addr, port: u16) -> Self {
118 Self::new(ip, port)
119 }
120
121 fn ip(&self) -> <Self::Family as AnyIpFamily>::Addr {
122 *self.ip()
123 }
124
125 fn set_ip(&mut self, new_ip: <Self::Family as AnyIpFamily>::Addr) {
126 self.set_ip(new_ip)
127 }
128
129 fn port(&self) -> u16 {
130 self.port()
131 }
132
133 fn set_port(&mut self, new_port: u16) {
134 self.set_port(new_port)
135 }
136}
137
138pub struct IpFamilyV6;
139
140impl sealed::Sealed for IpFamilyV6 {}
141impl AnyIpFamily for IpFamilyV6 {
142 type Addr = Ipv6Addr;
143
144 type SocketAddr = SocketAddrV6;
145
146 const FAMILY: IpFamily = IpFamily::V6;
147}
148
149const IPV6_ADDR_BYTES: usize = 16;
150impl sealed::Sealed for Ipv6Addr {}
151impl IpFamilyAddr for Ipv6Addr {
152 type Family = IpFamilyV6;
153 type Raw = u128;
154 type Bytes = [u8; IPV6_ADDR_BYTES];
155
156 const BYTES: usize = IPV6_ADDR_BYTES;
157 const LOCALHOST: Self = Self::LOCALHOST;
158 const UNSPECIFIED: Self = Self::UNSPECIFIED;
159
160 fn octets(&self) -> Self::Bytes {
161 self.octets()
162 }
163
164 fn is_unspecified(&self) -> bool {
165 self.is_unspecified()
166 }
167
168 fn is_loopback(&self) -> bool {
169 self.is_loopback()
170 }
171
172 fn is_multicast(&self) -> bool {
173 self.is_multicast()
174 }
175}
176
177impl sealed::Sealed for SocketAddrV6 {}
178impl IpFamilySocketAddr for SocketAddrV6 {
179 type Family = IpFamilyV6;
180
181 fn new(ip: <Self::Family as AnyIpFamily>::Addr, port: u16) -> Self {
182 Self::new(ip, port, 0, 0)
183 }
184
185 fn ip(&self) -> <Self::Family as AnyIpFamily>::Addr {
186 *self.ip()
187 }
188
189 fn set_ip(&mut self, new_ip: <Self::Family as AnyIpFamily>::Addr) {
190 self.set_ip(new_ip)
191 }
192
193 fn port(&self) -> u16 {
194 self.port()
195 }
196
197 fn set_port(&mut self, new_port: u16) {
198 self.set_port(new_port)
199 }
200}
201
202#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
203pub enum IpFamily {
204 V4,
205 V6,
206}
207
208impl IpFamily {
209 pub const fn localhost(&self) -> IpAddr {
210 match self {
211 Self::V4 => IpAddr::V4(Ipv4Addr::LOCALHOST),
212 Self::V6 => IpAddr::V6(Ipv6Addr::LOCALHOST),
213 }
214 }
215
216 pub const fn unspecified(&self) -> IpAddr {
217 match self {
218 Self::V4 => IpAddr::V4(Ipv4Addr::UNSPECIFIED),
219 Self::V6 => IpAddr::V6(Ipv6Addr::UNSPECIFIED),
220 }
221 }
222}
223
224impl AsRef<IpFamily> for IpAddr {
225 fn as_ref(&self) -> &IpFamily {
226 match self {
227 IpAddr::V4(_) => &IpFamily::V4,
228 IpAddr::V6(_) => &IpFamily::V6,
229 }
230 }
231}
232
233impl AsRef<IpFamily> for SocketAddr {
234 fn as_ref(&self) -> &IpFamily {
235 match self {
236 SocketAddr::V4(_) => &IpFamily::V4,
237 SocketAddr::V6(_) => &IpFamily::V6,
238 }
239 }
240}
241
242impl<T: AsRef<IpFamily>> From<T> for IpFamily {
243 fn from(value: T) -> Self {
244 *value.as_ref()
245 }
246}
247
248pub trait IpFamilyExt {
249 fn family(&self) -> IpFamily;
250}
251
252impl<T: AsRef<IpFamily>> IpFamilyExt for T {
253 fn family(&self) -> IpFamily {
254 *self.as_ref()
255 }
256}