1use crate::{
2 net::{
3 ArchivedIpAddr, ArchivedIpv4Addr, ArchivedIpv6Addr, ArchivedSocketAddr,
4 ArchivedSocketAddrV4, ArchivedSocketAddrV6,
5 },
6 Archive, Deserialize, Fallible, Serialize,
7};
8use core::{cmp, ptr};
9use std::{
10 io,
11 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},
12};
13
14impl ArchivedIpv4Addr {
17 #[inline]
19 pub const fn as_ipv4(&self) -> Ipv4Addr {
20 let octets = self.octets();
21 Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3])
22 }
23
24 #[inline]
28 pub const fn is_broadcast(&self) -> bool {
29 self.as_ipv4().is_broadcast()
30 }
31
32 #[inline]
36 pub const fn is_documentation(&self) -> bool {
37 self.as_ipv4().is_documentation()
38 }
39
40 #[inline]
44 pub const fn is_link_local(&self) -> bool {
45 self.as_ipv4().is_link_local()
46 }
47
48 #[inline]
52 pub const fn is_loopback(&self) -> bool {
53 self.as_ipv4().is_loopback()
54 }
55
56 #[inline]
60 pub const fn is_multicast(&self) -> bool {
61 self.as_ipv4().is_multicast()
62 }
63
64 #[inline]
68 pub const fn is_private(&self) -> bool {
69 self.as_ipv4().is_private()
70 }
71
72 #[inline]
76 pub const fn is_unspecified(&self) -> bool {
77 self.as_ipv4().is_unspecified()
78 }
79
80 #[inline]
85 #[allow(clippy::wrong_self_convention)]
86 pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
87 self.as_ipv4().to_ipv6_compatible()
88 }
89
90 #[inline]
94 #[allow(clippy::wrong_self_convention)]
95 pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
96 self.as_ipv4().to_ipv6_mapped()
97 }
98}
99
100impl PartialEq<Ipv4Addr> for ArchivedIpv4Addr {
101 #[inline]
102 fn eq(&self, other: &Ipv4Addr) -> bool {
103 self.as_ipv4().eq(other)
104 }
105}
106
107impl PartialEq<ArchivedIpv4Addr> for Ipv4Addr {
108 #[inline]
109 fn eq(&self, other: &ArchivedIpv4Addr) -> bool {
110 other.eq(self)
111 }
112}
113
114impl PartialOrd<Ipv4Addr> for ArchivedIpv4Addr {
115 #[inline]
116 fn partial_cmp(&self, other: &Ipv4Addr) -> Option<cmp::Ordering> {
117 self.as_ipv4().partial_cmp(other)
118 }
119}
120
121impl PartialOrd<ArchivedIpv4Addr> for Ipv4Addr {
122 #[inline]
123 fn partial_cmp(&self, other: &ArchivedIpv4Addr) -> Option<cmp::Ordering> {
124 other.partial_cmp(self)
125 }
126}
127
128impl Archive for Ipv4Addr {
129 type Archived = ArchivedIpv4Addr;
130 type Resolver = ();
131
132 #[inline]
133 unsafe fn resolve(&self, _: usize, _: Self::Resolver, out: *mut Self::Archived) {
134 out.cast::<[u8; 4]>().write(self.octets());
135 }
136}
137
138impl<S: Fallible + ?Sized> Serialize<S> for Ipv4Addr {
139 #[inline]
140 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
141 Ok(())
142 }
143}
144
145impl<D: Fallible + ?Sized> Deserialize<Ipv4Addr, D> for ArchivedIpv4Addr {
146 #[inline]
147 fn deserialize(&self, _: &mut D) -> Result<Ipv4Addr, D::Error> {
148 Ok(self.as_ipv4())
149 }
150}
151
152impl ArchivedIpv6Addr {
155 #[inline]
157 pub const fn as_ipv6(&self) -> Ipv6Addr {
158 let segments = self.segments();
159 Ipv6Addr::new(
160 segments[0],
161 segments[1],
162 segments[2],
163 segments[3],
164 segments[4],
165 segments[5],
166 segments[6],
167 segments[7],
168 )
169 }
170
171 #[inline]
175 pub const fn is_loopback(&self) -> bool {
176 self.as_ipv6().is_loopback()
177 }
178
179 #[inline]
183 pub const fn is_multicast(&self) -> bool {
184 self.as_ipv6().is_multicast()
185 }
186
187 #[inline]
191 pub const fn is_unspecified(&self) -> bool {
192 self.as_ipv6().is_unspecified()
193 }
194
195 #[inline]
197 pub const fn octets(&self) -> [u8; 16] {
198 self.as_ipv6().octets()
199 }
200
201 #[inline]
205 #[allow(clippy::wrong_self_convention)]
206 pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
207 self.as_ipv6().to_ipv4()
208 }
209}
210
211impl PartialEq<Ipv6Addr> for ArchivedIpv6Addr {
212 #[inline]
213 fn eq(&self, other: &Ipv6Addr) -> bool {
214 self.as_ipv6().eq(other)
215 }
216}
217
218impl PartialEq<ArchivedIpv6Addr> for Ipv6Addr {
219 #[inline]
220 fn eq(&self, other: &ArchivedIpv6Addr) -> bool {
221 other.eq(self)
222 }
223}
224
225impl PartialOrd<Ipv6Addr> for ArchivedIpv6Addr {
226 #[inline]
227 fn partial_cmp(&self, other: &Ipv6Addr) -> Option<cmp::Ordering> {
228 self.as_ipv6().partial_cmp(other)
229 }
230}
231
232impl PartialOrd<ArchivedIpv6Addr> for Ipv6Addr {
233 #[inline]
234 fn partial_cmp(&self, other: &ArchivedIpv6Addr) -> Option<cmp::Ordering> {
235 other.partial_cmp(self)
236 }
237}
238
239impl Archive for Ipv6Addr {
240 type Archived = ArchivedIpv6Addr;
241 type Resolver = ();
242
243 #[inline]
244 unsafe fn resolve(&self, _: usize, _: Self::Resolver, out: *mut Self::Archived) {
245 out.cast::<[u8; 16]>().write(self.octets());
246 }
247}
248
249impl<S: Fallible + ?Sized> Serialize<S> for Ipv6Addr {
250 #[inline]
251 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
252 Ok(())
253 }
254}
255
256impl<D: Fallible + ?Sized> Deserialize<Ipv6Addr, D> for ArchivedIpv6Addr {
257 #[inline]
258 fn deserialize(&self, _: &mut D) -> Result<Ipv6Addr, D::Error> {
259 Ok(self.as_ipv6())
260 }
261}
262
263impl ArchivedIpAddr {
266 #[inline]
268 pub const fn as_ipaddr(&self) -> IpAddr {
269 match self {
270 ArchivedIpAddr::V4(ipv4) => IpAddr::V4(ipv4.as_ipv4()),
271 ArchivedIpAddr::V6(ipv6) => IpAddr::V6(ipv6.as_ipv6()),
272 }
273 }
274
275 #[inline]
279 pub const fn is_loopback(&self) -> bool {
280 match self {
281 ArchivedIpAddr::V4(ip) => ip.is_loopback(),
282 ArchivedIpAddr::V6(ip) => ip.is_loopback(),
283 }
284 }
285
286 #[inline]
290 pub const fn is_multicast(&self) -> bool {
291 match self {
292 ArchivedIpAddr::V4(ip) => ip.is_multicast(),
293 ArchivedIpAddr::V6(ip) => ip.is_multicast(),
294 }
295 }
296
297 #[inline]
301 pub const fn is_unspecified(&self) -> bool {
302 match self {
303 ArchivedIpAddr::V4(ip) => ip.is_unspecified(),
304 ArchivedIpAddr::V6(ip) => ip.is_unspecified(),
305 }
306 }
307}
308
309impl PartialEq<IpAddr> for ArchivedIpAddr {
310 #[inline]
311 fn eq(&self, other: &IpAddr) -> bool {
312 match self {
313 ArchivedIpAddr::V4(self_ip) => {
314 if let IpAddr::V4(other_ip) = other {
315 self_ip.eq(other_ip)
316 } else {
317 false
318 }
319 }
320 ArchivedIpAddr::V6(self_ip) => {
321 if let IpAddr::V6(other_ip) = other {
322 self_ip.eq(other_ip)
323 } else {
324 false
325 }
326 }
327 }
328 }
329}
330
331impl PartialEq<ArchivedIpAddr> for IpAddr {
332 #[inline]
333 fn eq(&self, other: &ArchivedIpAddr) -> bool {
334 other.eq(self)
335 }
336}
337
338impl PartialOrd<IpAddr> for ArchivedIpAddr {
339 #[inline]
340 fn partial_cmp(&self, other: &IpAddr) -> Option<cmp::Ordering> {
341 self.as_ipaddr().partial_cmp(other)
342 }
343}
344
345impl PartialOrd<ArchivedIpAddr> for IpAddr {
346 #[inline]
347 fn partial_cmp(&self, other: &ArchivedIpAddr) -> Option<cmp::Ordering> {
348 other.partial_cmp(self)
349 }
350}
351
352#[allow(dead_code)]
353#[repr(u8)]
354enum ArchivedIpAddrTag {
355 V4,
356 V6,
357}
358
359#[repr(C)]
360struct ArchivedIpAddrVariantV4(ArchivedIpAddrTag, ArchivedIpv4Addr);
361
362#[repr(C)]
363struct ArchivedIpAddrVariantV6(ArchivedIpAddrTag, ArchivedIpv6Addr);
364
365impl Archive for IpAddr {
366 type Archived = ArchivedIpAddr;
367 type Resolver = ();
368
369 #[inline]
370 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
371 match self {
372 IpAddr::V4(ipv4_addr) => {
373 let out = out.cast::<ArchivedIpAddrVariantV4>();
374 ptr::addr_of_mut!((*out).0).write(ArchivedIpAddrTag::V4);
375
376 let (fp, fo) = out_field!(out.1);
377 #[allow(clippy::unit_arg)]
379 ipv4_addr.resolve(pos + fp, resolver, fo);
380 }
381 IpAddr::V6(ipv6_addr) => {
382 let out = out.cast::<ArchivedIpAddrVariantV6>();
383 ptr::addr_of_mut!((*out).0).write(ArchivedIpAddrTag::V6);
384
385 let (fp, fo) = out_field!(out.1);
386 #[allow(clippy::unit_arg)]
388 ipv6_addr.resolve(pos + fp, resolver, fo);
389 }
390 }
391 }
392}
393
394impl<S: Fallible + ?Sized> Serialize<S> for IpAddr {
395 #[inline]
396 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
397 match self {
398 IpAddr::V4(ipv4_addr) => ipv4_addr.serialize(serializer),
399 IpAddr::V6(ipv6_addr) => ipv6_addr.serialize(serializer),
400 }
401 }
402}
403
404impl<D: Fallible + ?Sized> Deserialize<IpAddr, D> for ArchivedIpAddr {
405 #[inline]
406 fn deserialize(&self, deserializer: &mut D) -> Result<IpAddr, D::Error> {
407 match self {
408 ArchivedIpAddr::V4(ipv4_addr) => Ok(IpAddr::V4(ipv4_addr.deserialize(deserializer)?)),
409 ArchivedIpAddr::V6(ipv6_addr) => Ok(IpAddr::V6(ipv6_addr.deserialize(deserializer)?)),
410 }
411 }
412}
413
414impl ArchivedSocketAddrV4 {
417 #[inline]
419 pub fn as_socket_addr_v4(&self) -> SocketAddrV4 {
420 SocketAddrV4::new(self.ip().as_ipv4(), self.port())
421 }
422}
423
424impl ToSocketAddrs for ArchivedSocketAddrV4 {
425 type Iter = <SocketAddrV4 as ToSocketAddrs>::Iter;
426
427 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
428 self.as_socket_addr_v4().to_socket_addrs()
429 }
430}
431
432impl PartialEq<SocketAddrV4> for ArchivedSocketAddrV4 {
433 #[inline]
434 fn eq(&self, other: &SocketAddrV4) -> bool {
435 self.as_socket_addr_v4().eq(other)
436 }
437}
438
439impl PartialEq<ArchivedSocketAddrV4> for SocketAddrV4 {
440 #[inline]
441 fn eq(&self, other: &ArchivedSocketAddrV4) -> bool {
442 other.eq(self)
443 }
444}
445
446impl PartialOrd<SocketAddrV4> for ArchivedSocketAddrV4 {
447 #[inline]
448 fn partial_cmp(&self, other: &SocketAddrV4) -> Option<cmp::Ordering> {
449 self.as_socket_addr_v4().partial_cmp(other)
450 }
451}
452
453impl PartialOrd<ArchivedSocketAddrV4> for SocketAddrV4 {
454 #[inline]
455 fn partial_cmp(&self, other: &ArchivedSocketAddrV4) -> Option<cmp::Ordering> {
456 other.partial_cmp(self)
457 }
458}
459
460impl Archive for SocketAddrV4 {
461 type Archived = ArchivedSocketAddrV4;
462 type Resolver = ();
463
464 #[inline]
465 unsafe fn resolve(&self, pos: usize, _: Self::Resolver, out: *mut Self::Archived) {
466 let (fp, fo) = out_field!(out.ip);
467 self.ip().resolve(pos + fp, (), fo);
468 let (fp, fo) = out_field!(out.port);
469 self.port().resolve(pos + fp, (), fo);
470 }
471}
472
473impl<S: Fallible + ?Sized> Serialize<S> for SocketAddrV4 {
474 #[inline]
475 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
476 Ok(())
477 }
478}
479
480impl<D: Fallible + ?Sized> Deserialize<SocketAddrV4, D> for ArchivedSocketAddrV4 {
481 #[inline]
482 fn deserialize(&self, deserializer: &mut D) -> Result<SocketAddrV4, D::Error> {
483 let ip = self.ip().deserialize(deserializer)?;
484 Ok(SocketAddrV4::new(ip, self.port()))
485 }
486}
487
488impl ArchivedSocketAddrV6 {
491 #[inline]
493 pub fn as_socket_addr_v6(&self) -> SocketAddrV6 {
494 SocketAddrV6::new(
495 self.ip().as_ipv6(),
496 self.port(),
497 self.flowinfo(),
498 self.scope_id(),
499 )
500 }
501}
502
503impl ToSocketAddrs for ArchivedSocketAddrV6 {
504 type Iter = <SocketAddrV6 as ToSocketAddrs>::Iter;
505
506 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
507 self.as_socket_addr_v6().to_socket_addrs()
508 }
509}
510
511impl PartialEq<SocketAddrV6> for ArchivedSocketAddrV6 {
512 #[inline]
513 fn eq(&self, other: &SocketAddrV6) -> bool {
514 self.as_socket_addr_v6().eq(other)
515 }
516}
517
518impl PartialEq<ArchivedSocketAddrV6> for SocketAddrV6 {
519 #[inline]
520 fn eq(&self, other: &ArchivedSocketAddrV6) -> bool {
521 other.eq(self)
522 }
523}
524
525impl PartialOrd<SocketAddrV6> for ArchivedSocketAddrV6 {
526 #[inline]
527 fn partial_cmp(&self, other: &SocketAddrV6) -> Option<cmp::Ordering> {
528 self.as_socket_addr_v6().partial_cmp(other)
529 }
530}
531
532impl PartialOrd<ArchivedSocketAddrV6> for SocketAddrV6 {
533 #[inline]
534 fn partial_cmp(&self, other: &ArchivedSocketAddrV6) -> Option<cmp::Ordering> {
535 other.partial_cmp(self)
536 }
537}
538
539impl Archive for SocketAddrV6 {
540 type Archived = ArchivedSocketAddrV6;
541 type Resolver = ();
542
543 #[inline]
544 unsafe fn resolve(&self, pos: usize, _: Self::Resolver, out: *mut Self::Archived) {
545 let (fp, fo) = out_field!(out.ip);
546 self.ip().resolve(pos + fp, (), fo);
547 let (fp, fo) = out_field!(out.port);
548 self.port().resolve(pos + fp, (), fo);
549 let (fp, fo) = out_field!(out.flowinfo);
550 self.flowinfo().resolve(pos + fp, (), fo);
551 let (fp, fo) = out_field!(out.scope_id);
552 self.scope_id().resolve(pos + fp, (), fo);
553 }
554}
555
556impl<S: Fallible + ?Sized> Serialize<S> for SocketAddrV6 {
557 #[inline]
558 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
559 Ok(())
560 }
561}
562
563impl<D: Fallible + ?Sized> Deserialize<SocketAddrV6, D> for ArchivedSocketAddrV6 {
564 #[inline]
565 fn deserialize(&self, deserializer: &mut D) -> Result<SocketAddrV6, D::Error> {
566 let ip = self.ip().deserialize(deserializer)?;
567 Ok(SocketAddrV6::new(
568 ip,
569 self.port(),
570 self.flowinfo(),
571 self.scope_id(),
572 ))
573 }
574}
575
576impl ArchivedSocketAddr {
579 #[inline]
581 pub fn as_socket_addr(&self) -> SocketAddr {
582 match self {
583 ArchivedSocketAddr::V4(addr) => SocketAddr::V4(addr.as_socket_addr_v4()),
584 ArchivedSocketAddr::V6(addr) => SocketAddr::V6(addr.as_socket_addr_v6()),
585 }
586 }
587
588 #[inline]
590 pub fn ip(&self) -> IpAddr {
591 match self {
592 ArchivedSocketAddr::V4(addr) => IpAddr::V4(addr.ip().as_ipv4()),
593 ArchivedSocketAddr::V6(addr) => IpAddr::V6(addr.ip().as_ipv6()),
594 }
595 }
596}
597
598impl ToSocketAddrs for ArchivedSocketAddr {
599 type Iter = <SocketAddr as ToSocketAddrs>::Iter;
600
601 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
602 self.as_socket_addr().to_socket_addrs()
603 }
604}
605
606impl PartialEq<SocketAddr> for ArchivedSocketAddr {
607 #[inline]
608 fn eq(&self, other: &SocketAddr) -> bool {
609 self.as_socket_addr().eq(other)
610 }
611}
612
613impl PartialEq<ArchivedSocketAddr> for SocketAddr {
614 #[inline]
615 fn eq(&self, other: &ArchivedSocketAddr) -> bool {
616 other.eq(self)
617 }
618}
619
620impl PartialOrd<SocketAddr> for ArchivedSocketAddr {
621 #[inline]
622 fn partial_cmp(&self, other: &SocketAddr) -> Option<cmp::Ordering> {
623 self.as_socket_addr().partial_cmp(other)
624 }
625}
626
627impl PartialOrd<ArchivedSocketAddr> for SocketAddr {
628 #[inline]
629 fn partial_cmp(&self, other: &ArchivedSocketAddr) -> Option<cmp::Ordering> {
630 other.partial_cmp(self)
631 }
632}
633
634#[allow(dead_code)]
635#[repr(u8)]
636enum ArchivedSocketAddrTag {
637 V4,
638 V6,
639}
640
641#[repr(C)]
642struct ArchivedSocketAddrVariantV4(ArchivedSocketAddrTag, ArchivedSocketAddrV4);
643
644#[repr(C)]
645struct ArchivedSocketAddrVariantV6(ArchivedSocketAddrTag, ArchivedSocketAddrV6);
646
647impl Archive for SocketAddr {
648 type Archived = ArchivedSocketAddr;
649 type Resolver = ();
650
651 #[inline]
652 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
653 match self {
654 SocketAddr::V4(socket_addr) => {
655 let out = out.cast::<ArchivedSocketAddrVariantV4>();
656 ptr::addr_of_mut!((*out).0).write(ArchivedSocketAddrTag::V4);
657
658 let (fp, fo) = out_field!(out.1);
659 #[allow(clippy::unit_arg)]
661 socket_addr.resolve(pos + fp, resolver, fo);
662 }
663 SocketAddr::V6(socket_addr) => {
664 let out = out.cast::<ArchivedSocketAddrVariantV6>();
665 ptr::addr_of_mut!((*out).0).write(ArchivedSocketAddrTag::V6);
666
667 let (fp, fo) = out_field!(out.1);
668 #[allow(clippy::unit_arg)]
670 socket_addr.resolve(pos + fp, resolver, fo);
671 }
672 }
673 }
674}
675
676impl<S: Fallible + ?Sized> Serialize<S> for SocketAddr {
677 #[inline]
678 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
679 match self {
680 SocketAddr::V4(socket_addr) => socket_addr.serialize(serializer),
681 SocketAddr::V6(socket_addr) => socket_addr.serialize(serializer),
682 }
683 }
684}
685
686impl<D: Fallible + ?Sized> Deserialize<SocketAddr, D> for ArchivedSocketAddr {
687 #[inline]
688 fn deserialize(&self, deserializer: &mut D) -> Result<SocketAddr, D::Error> {
689 match self {
690 ArchivedSocketAddr::V4(socket_addr) => {
691 Ok(SocketAddr::V4(socket_addr.deserialize(deserializer)?))
692 }
693 ArchivedSocketAddr::V6(socket_addr) => {
694 Ok(SocketAddr::V6(socket_addr.deserialize(deserializer)?))
695 }
696 }
697 }
698}