rkyv/impls/std/
net.rs

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
14// Ipv4Addr
15
16impl ArchivedIpv4Addr {
17    /// Returns an [`Ipv4Addr`] with the same value.
18    #[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    /// Returns `true` if this is a broadcast address (255.255.255.255).
25    ///
26    /// See [`Ipv4Addr::is_broadcast()`](std::net::Ipv4Addr::is_broadcast()) for more details.
27    #[inline]
28    pub const fn is_broadcast(&self) -> bool {
29        self.as_ipv4().is_broadcast()
30    }
31
32    /// Returns `true` if this address is in a range designated for documentation.
33    ///
34    /// See [`Ipv4Addr::is_documentation()`](std::net::Ipv4Addr::is_documentation()) for more details.
35    #[inline]
36    pub const fn is_documentation(&self) -> bool {
37        self.as_ipv4().is_documentation()
38    }
39
40    /// Returns `true` if the address is link-local (169.254.0.0/16).
41    ///
42    /// See [`Ipv4Addr::is_link_local()`](std::net::Ipv4Addr::is_link_local()) for more details.
43    #[inline]
44    pub const fn is_link_local(&self) -> bool {
45        self.as_ipv4().is_link_local()
46    }
47
48    /// Returns `true` if this is a loopback address (127.0.0.0/8).
49    ///
50    /// See [`Ipv4Addr::is_loopback()`](std::net::Ipv4Addr::is_loopback()) for more details.
51    #[inline]
52    pub const fn is_loopback(&self) -> bool {
53        self.as_ipv4().is_loopback()
54    }
55
56    /// Returns `true` if this is a multicast address (224.0.0.0/4).
57    ///
58    /// See [`Ipv4Addr::is_multicast()`](std::net::Ipv4Addr::is_multicast()) for more details.
59    #[inline]
60    pub const fn is_multicast(&self) -> bool {
61        self.as_ipv4().is_multicast()
62    }
63
64    /// Returns `true` if this is a private address.
65    ///
66    /// See [`Ipv4Addr::is_private()`](std::net::Ipv4Addr::is_private()) for more details.
67    #[inline]
68    pub const fn is_private(&self) -> bool {
69        self.as_ipv4().is_private()
70    }
71
72    /// Returns `true` for the special 'unspecified' address (0.0.0.0).
73    ///
74    /// See [`Ipv4Addr::is_unspecified()`](std::net::Ipv4Addr::is_unspecified()) for more details.
75    #[inline]
76    pub const fn is_unspecified(&self) -> bool {
77        self.as_ipv4().is_unspecified()
78    }
79
80    /// Converts this address to an IPv4-compatible [`IPv6` address](std::net::Ipv6Addr).
81    ///
82    /// See [`Ipv4Addr::to_ipv6_compatible()`](std::net::Ipv4Addr::to_ipv6_compatible()) for more
83    /// details.
84    #[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    /// Converts this address to an IPv4-mapped [`IPv6` address](std::net::Ipv6Addr).
91    ///
92    /// See [`Ipv4Addr::to_ipv6_mapped()`](std::net::Ipv4Addr::to_ipv6_mapped()) for more details.
93    #[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
152// Ipv6Addr
153
154impl ArchivedIpv6Addr {
155    /// Returns an [`Ipv6Addr`] with the same value.
156    #[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    /// Returns `true` if this is a loopback address (::1).
172    ///
173    /// See [`Ipv6Addr::is_loopback()`](std::net::Ipv6Addr::is_loopback()) for more details.
174    #[inline]
175    pub const fn is_loopback(&self) -> bool {
176        self.as_ipv6().is_loopback()
177    }
178
179    /// Returns `true` if this is a multicast address (ff00::/8).
180    ///
181    /// See [`Ipv6Addr::is_multicast()`](std::net::Ipv6Addr::is_multicast()) for more details.
182    #[inline]
183    pub const fn is_multicast(&self) -> bool {
184        self.as_ipv6().is_multicast()
185    }
186
187    /// Returns `true` for the special 'unspecified' address (::).
188    ///
189    /// See [`Ipv6Addr::is_unspecified()`](std::net::Ipv6Addr::is_unspecified()) for more details.
190    #[inline]
191    pub const fn is_unspecified(&self) -> bool {
192        self.as_ipv6().is_unspecified()
193    }
194
195    /// Returns the sixteen eight-bit integers the IPv6 address consists of.
196    #[inline]
197    pub const fn octets(&self) -> [u8; 16] {
198        self.as_ipv6().octets()
199    }
200
201    /// Converts this address to an [`IPv4` address](std::net::Ipv4Addr). Returns
202    /// [`None`] if this address is neither IPv4-compatible or IPv4-mapped.
203    #[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
262// IpAddr
263
264impl ArchivedIpAddr {
265    /// Returns an [`IpAddr`] with the same value.
266    #[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    /// Returns `true` if this is a loopback address.
275    ///
276    /// See [`IpAddr::is_loopback()`](std::net::IpAddr::is_loopback()) for more details.
277    #[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    /// Returns `true` if this is a multicast address.
286    ///
287    /// See [`IpAddr::is_multicast()`](std::net::IpAddr::is_multicast()) for more details.
288    #[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    /// Returns `true` for the special 'unspecified' address.
297    ///
298    /// See [`IpAddr::is_unspecified()`](std::net::IpAddr::is_unspecified()) for more details.
299    #[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                // resolver is guaranteed to be (), but it's better to be explicit about it
377                #[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                // resolver is guaranteed to be (), but it's better to be explicit about it
386                #[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
413// SocketAddrV4
414
415impl ArchivedSocketAddrV4 {
416    /// Returns a [`SocketAddrV4`] with the same value.
417    #[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
487// SocketAddrV6
488
489impl ArchivedSocketAddrV6 {
490    /// Returns a [`SocketAddrV6`] with the same value.
491    #[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
575// SocketAddr
576
577impl ArchivedSocketAddr {
578    /// Returns a [`SocketAddr`] with the same value.
579    #[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    /// Returns the IP address associated with this socket address.
588    #[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                // resolver is guaranteed to be (), but it's better to be explicit about it
659                #[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                // resolver is guaranteed to be (), but it's better to be explicit about it
668                #[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}