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]
204 #[allow(clippy::wrong_self_convention)]
205 pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
206 self.as_ipv6().to_ipv4()
207 }
208}
209
210impl PartialEq<Ipv6Addr> for ArchivedIpv6Addr {
211 #[inline]
212 fn eq(&self, other: &Ipv6Addr) -> bool {
213 self.as_ipv6().eq(other)
214 }
215}
216
217impl PartialEq<ArchivedIpv6Addr> for Ipv6Addr {
218 #[inline]
219 fn eq(&self, other: &ArchivedIpv6Addr) -> bool {
220 other.eq(self)
221 }
222}
223
224impl PartialOrd<Ipv6Addr> for ArchivedIpv6Addr {
225 #[inline]
226 fn partial_cmp(&self, other: &Ipv6Addr) -> Option<cmp::Ordering> {
227 self.as_ipv6().partial_cmp(other)
228 }
229}
230
231impl PartialOrd<ArchivedIpv6Addr> for Ipv6Addr {
232 #[inline]
233 fn partial_cmp(&self, other: &ArchivedIpv6Addr) -> Option<cmp::Ordering> {
234 other.partial_cmp(self)
235 }
236}
237
238impl Archive for Ipv6Addr {
239 type Archived = ArchivedIpv6Addr;
240 type Resolver = ();
241
242 #[inline]
243 unsafe fn resolve(&self, _: usize, _: Self::Resolver, out: *mut Self::Archived) {
244 out.cast::<[u8; 16]>().write(self.octets());
245 }
246}
247
248impl<S: Fallible + ?Sized> Serialize<S> for Ipv6Addr {
249 #[inline]
250 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
251 Ok(())
252 }
253}
254
255impl<D: Fallible + ?Sized> Deserialize<Ipv6Addr, D> for ArchivedIpv6Addr {
256 #[inline]
257 fn deserialize(&self, _: &mut D) -> Result<Ipv6Addr, D::Error> {
258 Ok(self.as_ipv6())
259 }
260}
261
262impl ArchivedIpAddr {
265 #[inline]
267 pub const fn as_ipaddr(&self) -> IpAddr {
268 match self {
269 ArchivedIpAddr::V4(ipv4) => IpAddr::V4(ipv4.as_ipv4()),
270 ArchivedIpAddr::V6(ipv6) => IpAddr::V6(ipv6.as_ipv6()),
271 }
272 }
273
274 #[inline]
278 pub const fn is_loopback(&self) -> bool {
279 match self {
280 ArchivedIpAddr::V4(ip) => ip.is_loopback(),
281 ArchivedIpAddr::V6(ip) => ip.is_loopback(),
282 }
283 }
284
285 #[inline]
289 pub const fn is_multicast(&self) -> bool {
290 match self {
291 ArchivedIpAddr::V4(ip) => ip.is_multicast(),
292 ArchivedIpAddr::V6(ip) => ip.is_multicast(),
293 }
294 }
295
296 #[inline]
300 pub const fn is_unspecified(&self) -> bool {
301 match self {
302 ArchivedIpAddr::V4(ip) => ip.is_unspecified(),
303 ArchivedIpAddr::V6(ip) => ip.is_unspecified(),
304 }
305 }
306}
307
308impl PartialEq<IpAddr> for ArchivedIpAddr {
309 #[inline]
310 fn eq(&self, other: &IpAddr) -> bool {
311 match self {
312 ArchivedIpAddr::V4(self_ip) => {
313 if let IpAddr::V4(other_ip) = other {
314 self_ip.eq(other_ip)
315 } else {
316 false
317 }
318 }
319 ArchivedIpAddr::V6(self_ip) => {
320 if let IpAddr::V6(other_ip) = other {
321 self_ip.eq(other_ip)
322 } else {
323 false
324 }
325 }
326 }
327 }
328}
329
330impl PartialEq<ArchivedIpAddr> for IpAddr {
331 #[inline]
332 fn eq(&self, other: &ArchivedIpAddr) -> bool {
333 other.eq(self)
334 }
335}
336
337impl PartialOrd<IpAddr> for ArchivedIpAddr {
338 #[inline]
339 fn partial_cmp(&self, other: &IpAddr) -> Option<cmp::Ordering> {
340 self.as_ipaddr().partial_cmp(other)
341 }
342}
343
344impl PartialOrd<ArchivedIpAddr> for IpAddr {
345 #[inline]
346 fn partial_cmp(&self, other: &ArchivedIpAddr) -> Option<cmp::Ordering> {
347 other.partial_cmp(self)
348 }
349}
350
351#[allow(dead_code)]
352#[repr(u8)]
353enum ArchivedIpAddrTag {
354 V4,
355 V6,
356}
357
358#[repr(C)]
359struct ArchivedIpAddrVariantV4(ArchivedIpAddrTag, ArchivedIpv4Addr);
360
361#[repr(C)]
362struct ArchivedIpAddrVariantV6(ArchivedIpAddrTag, ArchivedIpv6Addr);
363
364impl Archive for IpAddr {
365 type Archived = ArchivedIpAddr;
366 type Resolver = ();
367
368 #[inline]
369 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
370 match self {
371 IpAddr::V4(ipv4_addr) => {
372 let out = out.cast::<ArchivedIpAddrVariantV4>();
373 ptr::addr_of_mut!((*out).0).write(ArchivedIpAddrTag::V4);
374
375 let (fp, fo) = out_field!(out.1);
376 #[allow(clippy::unit_arg)]
378 ipv4_addr.resolve(pos + fp, resolver, fo);
379 }
380 IpAddr::V6(ipv6_addr) => {
381 let out = out.cast::<ArchivedIpAddrVariantV6>();
382 ptr::addr_of_mut!((*out).0).write(ArchivedIpAddrTag::V6);
383
384 let (fp, fo) = out_field!(out.1);
385 #[allow(clippy::unit_arg)]
387 ipv6_addr.resolve(pos + fp, resolver, fo);
388 }
389 }
390 }
391}
392
393impl<S: Fallible + ?Sized> Serialize<S> for IpAddr {
394 #[inline]
395 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
396 match self {
397 IpAddr::V4(ipv4_addr) => ipv4_addr.serialize(serializer),
398 IpAddr::V6(ipv6_addr) => ipv6_addr.serialize(serializer),
399 }
400 }
401}
402
403impl<D: Fallible + ?Sized> Deserialize<IpAddr, D> for ArchivedIpAddr {
404 #[inline]
405 fn deserialize(&self, deserializer: &mut D) -> Result<IpAddr, D::Error> {
406 match self {
407 ArchivedIpAddr::V4(ipv4_addr) => Ok(IpAddr::V4(ipv4_addr.deserialize(deserializer)?)),
408 ArchivedIpAddr::V6(ipv6_addr) => Ok(IpAddr::V6(ipv6_addr.deserialize(deserializer)?)),
409 }
410 }
411}
412
413impl ArchivedSocketAddrV4 {
416 #[inline]
418 pub fn as_socket_addr_v4(&self) -> SocketAddrV4 {
419 SocketAddrV4::new(self.ip().as_ipv4(), self.port())
420 }
421}
422
423impl ToSocketAddrs for ArchivedSocketAddrV4 {
424 type Iter = <SocketAddrV4 as ToSocketAddrs>::Iter;
425
426 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
427 self.as_socket_addr_v4().to_socket_addrs()
428 }
429}
430
431impl PartialEq<SocketAddrV4> for ArchivedSocketAddrV4 {
432 #[inline]
433 fn eq(&self, other: &SocketAddrV4) -> bool {
434 self.as_socket_addr_v4().eq(other)
435 }
436}
437
438impl PartialEq<ArchivedSocketAddrV4> for SocketAddrV4 {
439 #[inline]
440 fn eq(&self, other: &ArchivedSocketAddrV4) -> bool {
441 other.eq(self)
442 }
443}
444
445impl PartialOrd<SocketAddrV4> for ArchivedSocketAddrV4 {
446 #[inline]
447 fn partial_cmp(&self, other: &SocketAddrV4) -> Option<cmp::Ordering> {
448 self.as_socket_addr_v4().partial_cmp(other)
449 }
450}
451
452impl PartialOrd<ArchivedSocketAddrV4> for SocketAddrV4 {
453 #[inline]
454 fn partial_cmp(&self, other: &ArchivedSocketAddrV4) -> Option<cmp::Ordering> {
455 other.partial_cmp(self)
456 }
457}
458
459impl Archive for SocketAddrV4 {
460 type Archived = ArchivedSocketAddrV4;
461 type Resolver = ();
462
463 #[inline]
464 unsafe fn resolve(&self, pos: usize, _: Self::Resolver, out: *mut Self::Archived) {
465 let (fp, fo) = out_field!(out.ip);
466 self.ip().resolve(pos + fp, (), fo);
467 let (fp, fo) = out_field!(out.port);
468 self.port().resolve(pos + fp, (), fo);
469 }
470}
471
472impl<S: Fallible + ?Sized> Serialize<S> for SocketAddrV4 {
473 #[inline]
474 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
475 Ok(())
476 }
477}
478
479impl<D: Fallible + ?Sized> Deserialize<SocketAddrV4, D> for ArchivedSocketAddrV4 {
480 #[inline]
481 fn deserialize(&self, deserializer: &mut D) -> Result<SocketAddrV4, D::Error> {
482 let ip = self.ip().deserialize(deserializer)?;
483 Ok(SocketAddrV4::new(ip, self.port()))
484 }
485}
486
487impl ArchivedSocketAddrV6 {
490 #[inline]
492 pub fn as_socket_addr_v6(&self) -> SocketAddrV6 {
493 SocketAddrV6::new(
494 self.ip().as_ipv6(),
495 self.port(),
496 self.flowinfo(),
497 self.scope_id(),
498 )
499 }
500}
501
502impl ToSocketAddrs for ArchivedSocketAddrV6 {
503 type Iter = <SocketAddrV6 as ToSocketAddrs>::Iter;
504
505 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
506 self.as_socket_addr_v6().to_socket_addrs()
507 }
508}
509
510impl PartialEq<SocketAddrV6> for ArchivedSocketAddrV6 {
511 #[inline]
512 fn eq(&self, other: &SocketAddrV6) -> bool {
513 self.as_socket_addr_v6().eq(other)
514 }
515}
516
517impl PartialEq<ArchivedSocketAddrV6> for SocketAddrV6 {
518 #[inline]
519 fn eq(&self, other: &ArchivedSocketAddrV6) -> bool {
520 other.eq(self)
521 }
522}
523
524impl PartialOrd<SocketAddrV6> for ArchivedSocketAddrV6 {
525 #[inline]
526 fn partial_cmp(&self, other: &SocketAddrV6) -> Option<cmp::Ordering> {
527 self.as_socket_addr_v6().partial_cmp(other)
528 }
529}
530
531impl PartialOrd<ArchivedSocketAddrV6> for SocketAddrV6 {
532 #[inline]
533 fn partial_cmp(&self, other: &ArchivedSocketAddrV6) -> Option<cmp::Ordering> {
534 other.partial_cmp(self)
535 }
536}
537
538impl Archive for SocketAddrV6 {
539 type Archived = ArchivedSocketAddrV6;
540 type Resolver = ();
541
542 #[inline]
543 unsafe fn resolve(&self, pos: usize, _: Self::Resolver, out: *mut Self::Archived) {
544 let (fp, fo) = out_field!(out.ip);
545 self.ip().resolve(pos + fp, (), fo);
546 let (fp, fo) = out_field!(out.port);
547 self.port().resolve(pos + fp, (), fo);
548 let (fp, fo) = out_field!(out.flowinfo);
549 self.flowinfo().resolve(pos + fp, (), fo);
550 let (fp, fo) = out_field!(out.scope_id);
551 self.scope_id().resolve(pos + fp, (), fo);
552 }
553}
554
555impl<S: Fallible + ?Sized> Serialize<S> for SocketAddrV6 {
556 #[inline]
557 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
558 Ok(())
559 }
560}
561
562impl<D: Fallible + ?Sized> Deserialize<SocketAddrV6, D> for ArchivedSocketAddrV6 {
563 #[inline]
564 fn deserialize(&self, deserializer: &mut D) -> Result<SocketAddrV6, D::Error> {
565 let ip = self.ip().deserialize(deserializer)?;
566 Ok(SocketAddrV6::new(
567 ip,
568 self.port(),
569 self.flowinfo(),
570 self.scope_id(),
571 ))
572 }
573}
574
575impl ArchivedSocketAddr {
578 #[inline]
580 pub fn as_socket_addr(&self) -> SocketAddr {
581 match self {
582 ArchivedSocketAddr::V4(addr) => SocketAddr::V4(addr.as_socket_addr_v4()),
583 ArchivedSocketAddr::V6(addr) => SocketAddr::V6(addr.as_socket_addr_v6()),
584 }
585 }
586
587 #[inline]
589 pub fn ip(&self) -> IpAddr {
590 match self {
591 ArchivedSocketAddr::V4(addr) => IpAddr::V4(addr.ip().as_ipv4()),
592 ArchivedSocketAddr::V6(addr) => IpAddr::V6(addr.ip().as_ipv6()),
593 }
594 }
595}
596
597impl ToSocketAddrs for ArchivedSocketAddr {
598 type Iter = <SocketAddr as ToSocketAddrs>::Iter;
599
600 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
601 self.as_socket_addr().to_socket_addrs()
602 }
603}
604
605impl PartialEq<SocketAddr> for ArchivedSocketAddr {
606 #[inline]
607 fn eq(&self, other: &SocketAddr) -> bool {
608 self.as_socket_addr().eq(other)
609 }
610}
611
612impl PartialEq<ArchivedSocketAddr> for SocketAddr {
613 #[inline]
614 fn eq(&self, other: &ArchivedSocketAddr) -> bool {
615 other.eq(self)
616 }
617}
618
619impl PartialOrd<SocketAddr> for ArchivedSocketAddr {
620 #[inline]
621 fn partial_cmp(&self, other: &SocketAddr) -> Option<cmp::Ordering> {
622 self.as_socket_addr().partial_cmp(other)
623 }
624}
625
626impl PartialOrd<ArchivedSocketAddr> for SocketAddr {
627 #[inline]
628 fn partial_cmp(&self, other: &ArchivedSocketAddr) -> Option<cmp::Ordering> {
629 other.partial_cmp(self)
630 }
631}
632
633#[allow(dead_code)]
634#[repr(u8)]
635enum ArchivedSocketAddrTag {
636 V4,
637 V6,
638}
639
640#[repr(C)]
641struct ArchivedSocketAddrVariantV4(ArchivedSocketAddrTag, ArchivedSocketAddrV4);
642
643#[repr(C)]
644struct ArchivedSocketAddrVariantV6(ArchivedSocketAddrTag, ArchivedSocketAddrV6);
645
646impl Archive for SocketAddr {
647 type Archived = ArchivedSocketAddr;
648 type Resolver = ();
649
650 #[inline]
651 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
652 match self {
653 SocketAddr::V4(socket_addr) => {
654 let out = out.cast::<ArchivedSocketAddrVariantV4>();
655 ptr::addr_of_mut!((*out).0).write(ArchivedSocketAddrTag::V4);
656
657 let (fp, fo) = out_field!(out.1);
658 #[allow(clippy::unit_arg)]
660 socket_addr.resolve(pos + fp, resolver, fo);
661 }
662 SocketAddr::V6(socket_addr) => {
663 let out = out.cast::<ArchivedSocketAddrVariantV6>();
664 ptr::addr_of_mut!((*out).0).write(ArchivedSocketAddrTag::V6);
665
666 let (fp, fo) = out_field!(out.1);
667 #[allow(clippy::unit_arg)]
669 socket_addr.resolve(pos + fp, resolver, fo);
670 }
671 }
672 }
673}
674
675impl<S: Fallible + ?Sized> Serialize<S> for SocketAddr {
676 #[inline]
677 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
678 match self {
679 SocketAddr::V4(socket_addr) => socket_addr.serialize(serializer),
680 SocketAddr::V6(socket_addr) => socket_addr.serialize(serializer),
681 }
682 }
683}
684
685impl<D: Fallible + ?Sized> Deserialize<SocketAddr, D> for ArchivedSocketAddr {
686 #[inline]
687 fn deserialize(&self, deserializer: &mut D) -> Result<SocketAddr, D::Error> {
688 match self {
689 ArchivedSocketAddr::V4(socket_addr) => {
690 Ok(SocketAddr::V4(socket_addr.deserialize(deserializer)?))
691 }
692 ArchivedSocketAddr::V6(socket_addr) => {
693 Ok(SocketAddr::V6(socket_addr.deserialize(deserializer)?))
694 }
695 }
696 }
697}