1use core::{
2 cmp,
3 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
4};
5
6use munge::munge;
7use rancor::Fallible;
8
9use crate::{
10 net::{
11 ArchivedIpAddr, ArchivedIpv4Addr, ArchivedIpv6Addr, ArchivedSocketAddr,
12 ArchivedSocketAddrV4, ArchivedSocketAddrV6,
13 },
14 traits::NoUndef,
15 Archive, Deserialize, Place, Serialize,
16};
17
18impl Archive for Ipv4Addr {
21 type Archived = ArchivedIpv4Addr;
22 type Resolver = ();
23
24 #[inline]
25 fn resolve(&self, _: Self::Resolver, out: Place<Self::Archived>) {
26 ArchivedIpv4Addr::emplace(self.octets(), out);
27 }
28}
29
30impl<S: Fallible + ?Sized> Serialize<S> for Ipv4Addr {
31 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
32 Ok(())
33 }
34}
35
36impl<D: Fallible + ?Sized> Deserialize<Ipv4Addr, D> for ArchivedIpv4Addr {
37 fn deserialize(&self, _: &mut D) -> Result<Ipv4Addr, D::Error> {
38 Ok(self.as_ipv4())
39 }
40}
41
42impl PartialEq<Ipv4Addr> for ArchivedIpv4Addr {
43 #[inline]
44 fn eq(&self, other: &Ipv4Addr) -> bool {
45 self.as_ipv4().eq(other)
46 }
47}
48
49impl PartialEq<ArchivedIpv4Addr> for Ipv4Addr {
50 #[inline]
51 fn eq(&self, other: &ArchivedIpv4Addr) -> bool {
52 other.eq(self)
53 }
54}
55
56impl PartialOrd<Ipv4Addr> for ArchivedIpv4Addr {
57 #[inline]
58 fn partial_cmp(&self, other: &Ipv4Addr) -> Option<cmp::Ordering> {
59 self.as_ipv4().partial_cmp(other)
60 }
61}
62
63impl PartialOrd<ArchivedIpv4Addr> for Ipv4Addr {
64 #[inline]
65 fn partial_cmp(&self, other: &ArchivedIpv4Addr) -> Option<cmp::Ordering> {
66 other.partial_cmp(self)
67 }
68}
69
70impl Archive for Ipv6Addr {
73 type Archived = ArchivedIpv6Addr;
74 type Resolver = ();
75
76 #[inline]
77 fn resolve(&self, _: Self::Resolver, out: Place<Self::Archived>) {
78 ArchivedIpv6Addr::emplace(self.octets(), out);
79 }
80}
81
82impl<S: Fallible + ?Sized> Serialize<S> for Ipv6Addr {
83 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
84 Ok(())
85 }
86}
87
88impl<D: Fallible + ?Sized> Deserialize<Ipv6Addr, D> for ArchivedIpv6Addr {
89 fn deserialize(&self, _: &mut D) -> Result<Ipv6Addr, D::Error> {
90 Ok(self.as_ipv6())
91 }
92}
93
94impl PartialEq<Ipv6Addr> for ArchivedIpv6Addr {
95 #[inline]
96 fn eq(&self, other: &Ipv6Addr) -> bool {
97 self.as_ipv6().eq(other)
98 }
99}
100
101impl PartialEq<ArchivedIpv6Addr> for Ipv6Addr {
102 #[inline]
103 fn eq(&self, other: &ArchivedIpv6Addr) -> bool {
104 other.eq(self)
105 }
106}
107
108impl PartialOrd<Ipv6Addr> for ArchivedIpv6Addr {
109 #[inline]
110 fn partial_cmp(&self, other: &Ipv6Addr) -> Option<cmp::Ordering> {
111 self.as_ipv6().partial_cmp(other)
112 }
113}
114
115impl PartialOrd<ArchivedIpv6Addr> for Ipv6Addr {
116 #[inline]
117 fn partial_cmp(&self, other: &ArchivedIpv6Addr) -> Option<cmp::Ordering> {
118 other.partial_cmp(self)
119 }
120}
121
122#[allow(dead_code)]
125#[repr(u8)]
126enum ArchivedIpAddrTag {
127 V4,
128 V6,
129}
130
131unsafe impl NoUndef for ArchivedIpAddrTag {}
134
135#[repr(C)]
136struct ArchivedIpAddrVariantV4(ArchivedIpAddrTag, ArchivedIpv4Addr);
137
138#[repr(C)]
139struct ArchivedIpAddrVariantV6(ArchivedIpAddrTag, ArchivedIpv6Addr);
140
141impl Archive for IpAddr {
142 type Archived = ArchivedIpAddr;
143 type Resolver = ();
144
145 #[inline]
146 fn resolve(&self, _: Self::Resolver, out: Place<Self::Archived>) {
147 match self {
148 IpAddr::V4(ipv4_addr) => {
149 let out =
150 unsafe { out.cast_unchecked::<ArchivedIpAddrVariantV4>() };
151 munge!(let ArchivedIpAddrVariantV4(tag, out_ipv4_addr) = out);
152 tag.write(ArchivedIpAddrTag::V4);
153 ArchivedIpv4Addr::emplace(ipv4_addr.octets(), out_ipv4_addr);
154 }
155 IpAddr::V6(ipv6_addr) => {
156 let out =
157 unsafe { out.cast_unchecked::<ArchivedIpAddrVariantV6>() };
158 munge!(let ArchivedIpAddrVariantV6(tag, out_ipv6_addr) = out);
159 tag.write(ArchivedIpAddrTag::V6);
160 ArchivedIpv6Addr::emplace(ipv6_addr.octets(), out_ipv6_addr);
161 }
162 }
163 }
164}
165
166impl<S: Fallible + ?Sized> Serialize<S> for IpAddr {
167 fn serialize(
168 &self,
169 serializer: &mut S,
170 ) -> Result<Self::Resolver, S::Error> {
171 match self {
172 IpAddr::V4(ipv4_addr) => ipv4_addr.serialize(serializer),
173 IpAddr::V6(ipv6_addr) => ipv6_addr.serialize(serializer),
174 }
175 }
176}
177
178impl<D: Fallible + ?Sized> Deserialize<IpAddr, D> for ArchivedIpAddr {
179 fn deserialize(&self, deserializer: &mut D) -> Result<IpAddr, D::Error> {
180 match self {
181 ArchivedIpAddr::V4(ipv4_addr) => {
182 Ok(IpAddr::V4(ipv4_addr.deserialize(deserializer)?))
183 }
184 ArchivedIpAddr::V6(ipv6_addr) => {
185 Ok(IpAddr::V6(ipv6_addr.deserialize(deserializer)?))
186 }
187 }
188 }
189}
190
191impl PartialEq<IpAddr> for ArchivedIpAddr {
192 #[inline]
193 fn eq(&self, other: &IpAddr) -> bool {
194 match self {
195 ArchivedIpAddr::V4(self_ip) => {
196 if let IpAddr::V4(other_ip) = other {
197 self_ip.eq(other_ip)
198 } else {
199 false
200 }
201 }
202 ArchivedIpAddr::V6(self_ip) => {
203 if let IpAddr::V6(other_ip) = other {
204 self_ip.eq(other_ip)
205 } else {
206 false
207 }
208 }
209 }
210 }
211}
212
213impl PartialEq<ArchivedIpAddr> for IpAddr {
214 #[inline]
215 fn eq(&self, other: &ArchivedIpAddr) -> bool {
216 other.eq(self)
217 }
218}
219
220impl PartialOrd<IpAddr> for ArchivedIpAddr {
221 #[inline]
222 fn partial_cmp(&self, other: &IpAddr) -> Option<cmp::Ordering> {
223 self.as_ipaddr().partial_cmp(other)
224 }
225}
226
227impl PartialOrd<ArchivedIpAddr> for IpAddr {
228 #[inline]
229 fn partial_cmp(&self, other: &ArchivedIpAddr) -> Option<cmp::Ordering> {
230 other.partial_cmp(self)
231 }
232}
233
234impl Archive for SocketAddrV4 {
237 type Archived = ArchivedSocketAddrV4;
238 type Resolver = ();
239
240 #[inline]
241 fn resolve(&self, _: Self::Resolver, out: Place<Self::Archived>) {
242 ArchivedSocketAddrV4::emplace(self, out);
243 }
244}
245
246impl<S: Fallible + ?Sized> Serialize<S> for SocketAddrV4 {
247 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
248 Ok(())
249 }
250}
251
252impl<D> Deserialize<SocketAddrV4, D> for ArchivedSocketAddrV4
253where
254 D: Fallible + ?Sized,
255{
256 fn deserialize(
257 &self,
258 deserializer: &mut D,
259 ) -> Result<SocketAddrV4, D::Error> {
260 let ip = self.ip().deserialize(deserializer)?;
261 Ok(SocketAddrV4::new(ip, self.port()))
262 }
263}
264
265impl PartialEq<SocketAddrV4> for ArchivedSocketAddrV4 {
266 #[inline]
267 fn eq(&self, other: &SocketAddrV4) -> bool {
268 self.as_socket_addr_v4().eq(other)
269 }
270}
271
272impl PartialEq<ArchivedSocketAddrV4> for SocketAddrV4 {
273 #[inline]
274 fn eq(&self, other: &ArchivedSocketAddrV4) -> bool {
275 other.eq(self)
276 }
277}
278
279impl PartialOrd<SocketAddrV4> for ArchivedSocketAddrV4 {
280 #[inline]
281 fn partial_cmp(&self, other: &SocketAddrV4) -> Option<cmp::Ordering> {
282 self.as_socket_addr_v4().partial_cmp(other)
283 }
284}
285
286impl PartialOrd<ArchivedSocketAddrV4> for SocketAddrV4 {
287 #[inline]
288 fn partial_cmp(
289 &self,
290 other: &ArchivedSocketAddrV4,
291 ) -> Option<cmp::Ordering> {
292 other.partial_cmp(self)
293 }
294}
295
296impl Archive for SocketAddrV6 {
299 type Archived = ArchivedSocketAddrV6;
300 type Resolver = ();
301
302 #[inline]
303 fn resolve(&self, _: Self::Resolver, out: Place<Self::Archived>) {
304 ArchivedSocketAddrV6::emplace(self, out);
305 }
306}
307
308impl<S: Fallible + ?Sized> Serialize<S> for SocketAddrV6 {
309 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
310 Ok(())
311 }
312}
313
314impl<D: Fallible + ?Sized> Deserialize<SocketAddrV6, D>
315 for ArchivedSocketAddrV6
316{
317 fn deserialize(
318 &self,
319 deserializer: &mut D,
320 ) -> Result<SocketAddrV6, D::Error> {
321 let ip = self.ip().deserialize(deserializer)?;
322 Ok(SocketAddrV6::new(
323 ip,
324 self.port(),
325 self.flowinfo(),
326 self.scope_id(),
327 ))
328 }
329}
330
331impl PartialEq<SocketAddrV6> for ArchivedSocketAddrV6 {
332 #[inline]
333 fn eq(&self, other: &SocketAddrV6) -> bool {
334 self.as_socket_addr_v6().eq(other)
335 }
336}
337
338impl PartialEq<ArchivedSocketAddrV6> for SocketAddrV6 {
339 #[inline]
340 fn eq(&self, other: &ArchivedSocketAddrV6) -> bool {
341 other.eq(self)
342 }
343}
344
345impl PartialOrd<SocketAddrV6> for ArchivedSocketAddrV6 {
346 #[inline]
347 fn partial_cmp(&self, other: &SocketAddrV6) -> Option<cmp::Ordering> {
348 self.as_socket_addr_v6().partial_cmp(other)
349 }
350}
351
352impl PartialOrd<ArchivedSocketAddrV6> for SocketAddrV6 {
353 #[inline]
354 fn partial_cmp(
355 &self,
356 other: &ArchivedSocketAddrV6,
357 ) -> Option<cmp::Ordering> {
358 other.partial_cmp(self)
359 }
360}
361
362#[allow(dead_code)]
365#[repr(u8)]
366enum ArchivedSocketAddrTag {
367 V4,
368 V6,
369}
370
371unsafe impl NoUndef for ArchivedSocketAddrTag {}
374
375#[repr(C)]
376struct ArchivedSocketAddrVariantV4(ArchivedSocketAddrTag, ArchivedSocketAddrV4);
377
378#[repr(C)]
379struct ArchivedSocketAddrVariantV6(ArchivedSocketAddrTag, ArchivedSocketAddrV6);
380
381impl Archive for SocketAddr {
382 type Archived = ArchivedSocketAddr;
383 type Resolver = ();
384
385 #[inline]
386 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
387 match self {
388 SocketAddr::V4(socket_addr) => {
389 let out = unsafe {
390 out.cast_unchecked::<ArchivedSocketAddrVariantV4>()
391 };
392 munge! {
393 let ArchivedSocketAddrVariantV4(tag, out_socket_addr) = out;
394 }
395 tag.write(ArchivedSocketAddrTag::V4);
396 socket_addr.resolve(resolver, out_socket_addr);
397 }
398 SocketAddr::V6(socket_addr) => {
399 let out = unsafe {
400 out.cast_unchecked::<ArchivedSocketAddrVariantV6>()
401 };
402 munge! {
403 let ArchivedSocketAddrVariantV6(tag, out_socket_addr) = out;
404 }
405 tag.write(ArchivedSocketAddrTag::V6);
406 socket_addr.resolve(resolver, out_socket_addr);
407 }
408 }
409 }
410}
411
412impl<S: Fallible + ?Sized> Serialize<S> for SocketAddr {
413 fn serialize(
414 &self,
415 serializer: &mut S,
416 ) -> Result<Self::Resolver, S::Error> {
417 match self {
418 SocketAddr::V4(socket_addr) => socket_addr.serialize(serializer),
419 SocketAddr::V6(socket_addr) => socket_addr.serialize(serializer),
420 }
421 }
422}
423
424impl<D: Fallible + ?Sized> Deserialize<SocketAddr, D> for ArchivedSocketAddr {
425 fn deserialize(
426 &self,
427 deserializer: &mut D,
428 ) -> Result<SocketAddr, D::Error> {
429 match self {
430 ArchivedSocketAddr::V4(socket_addr) => {
431 Ok(SocketAddr::V4(socket_addr.deserialize(deserializer)?))
432 }
433 ArchivedSocketAddr::V6(socket_addr) => {
434 Ok(SocketAddr::V6(socket_addr.deserialize(deserializer)?))
435 }
436 }
437 }
438}
439
440impl PartialEq<SocketAddr> for ArchivedSocketAddr {
441 #[inline]
442 fn eq(&self, other: &SocketAddr) -> bool {
443 self.as_socket_addr().eq(other)
444 }
445}
446
447impl PartialEq<ArchivedSocketAddr> for SocketAddr {
448 #[inline]
449 fn eq(&self, other: &ArchivedSocketAddr) -> bool {
450 other.eq(self)
451 }
452}
453
454impl PartialOrd<SocketAddr> for ArchivedSocketAddr {
455 #[inline]
456 fn partial_cmp(&self, other: &SocketAddr) -> Option<cmp::Ordering> {
457 self.as_socket_addr().partial_cmp(other)
458 }
459}
460
461impl PartialOrd<ArchivedSocketAddr> for SocketAddr {
462 #[inline]
463 fn partial_cmp(&self, other: &ArchivedSocketAddr) -> Option<cmp::Ordering> {
464 other.partial_cmp(self)
465 }
466}
467
468#[cfg(test)]
469mod tests {
470 use core::net::{
471 IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6,
472 };
473
474 use crate::api::test::roundtrip;
475
476 #[test]
477 fn roundtrip_ipv4_addr() {
478 roundtrip(&Ipv4Addr::new(31, 41, 59, 26));
479 }
480
481 #[test]
482 fn roundtrip_ipv6_addr() {
483 roundtrip(&Ipv6Addr::new(31, 41, 59, 26, 53, 58, 97, 93));
484 }
485
486 #[test]
487 fn roundtrip_ip_addr() {
488 roundtrip(&IpAddr::V4(Ipv4Addr::new(31, 41, 59, 26)));
489 roundtrip(&IpAddr::V6(Ipv6Addr::new(31, 41, 59, 26, 53, 58, 97, 93)));
490 }
491
492 #[test]
493 fn roundtrip_socket_addr_v4() {
494 roundtrip(&SocketAddrV4::new(Ipv4Addr::new(31, 41, 59, 26), 5358));
495 }
496
497 #[test]
498 fn roundtrip_socket_addr_v6() {
499 roundtrip(&SocketAddrV6::new(
500 Ipv6Addr::new(31, 31, 59, 26, 53, 58, 97, 93),
501 2384,
502 0,
503 0,
504 ));
505 }
506
507 #[test]
508 fn roundtrip_socket_addr() {
509 roundtrip(&SocketAddr::V4(SocketAddrV4::new(
510 Ipv4Addr::new(31, 41, 59, 26),
511 5358,
512 )));
513 roundtrip(&SocketAddr::V6(SocketAddrV6::new(
514 Ipv6Addr::new(31, 31, 59, 26, 53, 58, 97, 93),
515 2384,
516 0,
517 0,
518 )));
519 }
520}