rkyv/impls/core/
net.rs

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
18// Ipv4Addr
19
20impl 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
70// Ipv6Addr
71
72impl 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// IpAddr
123
124#[allow(dead_code)]
125#[repr(u8)]
126enum ArchivedIpAddrTag {
127    V4,
128    V6,
129}
130
131// SAFETY: `ArchivedIpArrdTag` is `repr(u8)` and so always consists of a single
132// well-defined byte.
133unsafe 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
234// SocketAddrV4
235
236impl 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
296// SocketAddrV6
297
298impl 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// SocketAddr
363
364#[allow(dead_code)]
365#[repr(u8)]
366enum ArchivedSocketAddrTag {
367    V4,
368    V6,
369}
370
371// SAFETY: `ArchivedSocketAddrTag` is `repr(u8)` and so always consists of a
372// single well-defined byte.
373unsafe 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}