musli_core/impls/
net.rs

1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
2use std::str::FromStr;
3
4use crate::de::{Decode, Decoder, SequenceDecoder, VariantDecoder};
5use crate::en::{Encode, Encoder, SequenceEncoder, VariantEncoder};
6use crate::mode::{Binary, Text};
7use crate::{Allocator, Context};
8
9#[derive(Encode, Decode)]
10#[musli(crate)]
11#[musli(Text, name_all = "kebab-case")]
12enum IpAddrTag {
13    Ipv4,
14    Ipv6,
15}
16
17#[derive(Encode, Decode)]
18#[musli(crate)]
19#[musli(Text, name_all = "kebab-case")]
20enum SocketAddrTag {
21    V4,
22    V6,
23}
24
25impl Encode<Binary> for Ipv4Addr {
26    type Encode = Self;
27
28    // Not packed since it doesn't have a strongly defined memory layout, even
29    // though it has a particular size.
30    const IS_BITWISE_ENCODE: bool = false;
31
32    #[inline]
33    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
34    where
35        E: Encoder,
36    {
37        encoder.encode_array(&self.octets())
38    }
39
40    #[inline]
41    fn as_encode(&self) -> &Self::Encode {
42        self
43    }
44}
45
46impl Encode<Text> for Ipv4Addr {
47    type Encode = Self;
48
49    // Not packed since it doesn't have a strongly defined memory layout, even
50    // though it has a particular size.
51    const IS_BITWISE_ENCODE: bool = false;
52
53    #[inline]
54    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
55    where
56        E: Encoder,
57    {
58        encoder.collect_string(self)
59    }
60
61    #[inline]
62    fn as_encode(&self) -> &Self::Encode {
63        self
64    }
65}
66
67impl<'de, A> Decode<'de, Binary, A> for Ipv4Addr
68where
69    A: Allocator,
70{
71    // Not packed since it doesn't have a strongly defined memory layout, even
72    // though it has a particular size.
73    const IS_BITWISE_DECODE: bool = false;
74
75    #[inline]
76    fn decode<D>(decoder: D) -> Result<Self, D::Error>
77    where
78        D: Decoder<'de>,
79    {
80        decoder.decode_array::<4>().map(Ipv4Addr::from)
81    }
82}
83
84impl<'de, A> Decode<'de, Text, A> for Ipv4Addr
85where
86    A: Allocator,
87{
88    // Not packed since it doesn't have a strongly defined memory layout, even
89    // though it has a particular size.
90    const IS_BITWISE_DECODE: bool = false;
91
92    #[inline]
93    fn decode<D>(decoder: D) -> Result<Self, D::Error>
94    where
95        D: Decoder<'de>,
96    {
97        let cx = decoder.cx();
98        decoder.decode_unsized(|string: &str| Ipv4Addr::from_str(string).map_err(cx.map()))
99    }
100}
101
102impl Encode<Binary> for Ipv6Addr {
103    type Encode = Self;
104
105    // Not packed since it doesn't have a strongly defined memory layout, even
106    // though it has a particular size.
107    const IS_BITWISE_ENCODE: bool = false;
108
109    #[inline]
110    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
111    where
112        E: Encoder<Mode = Binary>,
113    {
114        encoder.encode_array(&self.octets())
115    }
116
117    #[inline]
118    fn as_encode(&self) -> &Self::Encode {
119        self
120    }
121}
122
123impl Encode<Text> for Ipv6Addr {
124    type Encode = Self;
125
126    // Not packed since it doesn't have a strongly defined memory layout, even
127    // though it has a particular size.
128    const IS_BITWISE_ENCODE: bool = false;
129
130    #[inline]
131    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
132    where
133        E: Encoder<Mode = Text>,
134    {
135        encoder.collect_string(self)
136    }
137
138    #[inline]
139    fn as_encode(&self) -> &Self::Encode {
140        self
141    }
142}
143
144impl<'de, A> Decode<'de, Binary, A> for Ipv6Addr
145where
146    A: Allocator,
147{
148    // Not packed since it doesn't have a strongly defined memory layout, even
149    // though it has a particular size.
150    const IS_BITWISE_DECODE: bool = false;
151
152    #[inline]
153    fn decode<D>(decoder: D) -> Result<Self, D::Error>
154    where
155        D: Decoder<'de>,
156    {
157        decoder.decode_array::<16>().map(Ipv6Addr::from)
158    }
159}
160
161impl<'de, A> Decode<'de, Text, A> for Ipv6Addr
162where
163    A: Allocator,
164{
165    // Not packed since it doesn't have a strongly defined memory layout, even
166    // though it has a particular size.
167    const IS_BITWISE_DECODE: bool = false;
168
169    #[inline]
170    fn decode<D>(decoder: D) -> Result<Self, D::Error>
171    where
172        D: Decoder<'de>,
173    {
174        let cx = decoder.cx();
175        decoder.decode_unsized(|string: &str| Ipv6Addr::from_str(string).map_err(cx.map()))
176    }
177}
178
179impl<M> Encode<M> for IpAddr
180where
181    IpAddrTag: Encode<M>,
182    Ipv4Addr: Encode<M>,
183    Ipv6Addr: Encode<M>,
184{
185    type Encode = Self;
186
187    const IS_BITWISE_ENCODE: bool = false;
188
189    #[inline]
190    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
191    where
192        E: Encoder<Mode = M>,
193    {
194        let variant = encoder.encode_variant()?;
195
196        match self {
197            IpAddr::V4(v4) => variant.insert_variant(&IpAddrTag::Ipv4, v4),
198            IpAddr::V6(v6) => variant.insert_variant(&IpAddrTag::Ipv6, v6),
199        }
200    }
201
202    #[inline]
203    fn as_encode(&self) -> &Self::Encode {
204        self
205    }
206}
207
208impl<'de, M, A> Decode<'de, M, A> for IpAddr
209where
210    A: Allocator,
211    IpAddrTag: Decode<'de, M, A>,
212    Ipv4Addr: Decode<'de, M, A>,
213    Ipv6Addr: Decode<'de, M, A>,
214{
215    const IS_BITWISE_DECODE: bool = false;
216
217    #[inline]
218    fn decode<D>(decoder: D) -> Result<Self, D::Error>
219    where
220        D: Decoder<'de, Mode = M, Allocator = A>,
221    {
222        decoder.decode_variant(|variant| {
223            let tag = variant.decode_tag()?.decode()?;
224
225            Ok(match tag {
226                IpAddrTag::Ipv4 => Self::V4(variant.decode_value()?.decode()?),
227                IpAddrTag::Ipv6 => Self::V6(variant.decode_value()?.decode()?),
228            })
229        })
230    }
231}
232
233impl Encode<Binary> for SocketAddrV4 {
234    type Encode = Self;
235
236    // Not packed since it doesn't have a strongly defined memory layout, even
237    // though it has a particular size.
238    const IS_BITWISE_ENCODE: bool = false;
239
240    #[inline]
241    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
242    where
243        E: Encoder<Mode = Binary>,
244    {
245        encoder.encode_pack_fn(|pack| {
246            pack.push(self.ip())?;
247            pack.push(self.port())?;
248            Ok(())
249        })
250    }
251
252    #[inline]
253    fn as_encode(&self) -> &Self::Encode {
254        self
255    }
256}
257
258impl Encode<Text> for SocketAddrV4 {
259    type Encode = Self;
260
261    // Not packed since it doesn't have a strongly defined memory layout, even
262    // though it has a particular size.
263    const IS_BITWISE_ENCODE: bool = false;
264
265    #[inline]
266    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
267    where
268        E: Encoder<Mode = Text>,
269    {
270        encoder.collect_string(self)
271    }
272
273    #[inline]
274    fn as_encode(&self) -> &Self::Encode {
275        self
276    }
277}
278
279impl<'de, A> Decode<'de, Binary, A> for SocketAddrV4
280where
281    A: Allocator,
282{
283    // Not packed since it doesn't have a strongly defined memory layout, even
284    // though it has a particular size.
285    const IS_BITWISE_DECODE: bool = false;
286
287    #[inline]
288    fn decode<D>(decoder: D) -> Result<Self, D::Error>
289    where
290        D: Decoder<'de, Mode = Binary>,
291    {
292        decoder.decode_pack(|p| Ok(SocketAddrV4::new(p.next()?, p.next()?)))
293    }
294}
295
296impl<'de, A> Decode<'de, Text, A> for SocketAddrV4
297where
298    A: Allocator,
299{
300    // Not packed since it doesn't have a strongly defined memory layout, even
301    // though it has a particular size.
302    const IS_BITWISE_DECODE: bool = false;
303
304    #[inline]
305    fn decode<D>(decoder: D) -> Result<Self, D::Error>
306    where
307        D: Decoder<'de>,
308    {
309        let cx = decoder.cx();
310        decoder.decode_unsized(|string: &str| SocketAddrV4::from_str(string).map_err(cx.map()))
311    }
312}
313
314impl Encode<Binary> for SocketAddrV6 {
315    type Encode = Self;
316
317    // Not packed since it doesn't have a strongly defined memory layout, even
318    // though it has a particular size.
319    const IS_BITWISE_ENCODE: bool = false;
320
321    #[inline]
322    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
323    where
324        E: Encoder<Mode = Binary>,
325    {
326        encoder.encode_pack_fn(|pack| {
327            pack.push(self.ip())?;
328            pack.push(self.port())?;
329            pack.push(self.flowinfo())?;
330            pack.push(self.scope_id())?;
331            Ok(())
332        })
333    }
334
335    #[inline]
336    fn as_encode(&self) -> &Self::Encode {
337        self
338    }
339}
340
341impl Encode<Text> for SocketAddrV6 {
342    type Encode = Self;
343
344    // Not packed since it doesn't have a strongly defined memory layout, even
345    // though it has a particular size.
346    const IS_BITWISE_ENCODE: bool = false;
347
348    #[inline]
349    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
350    where
351        E: Encoder<Mode = Text>,
352    {
353        encoder.collect_string(self)
354    }
355
356    #[inline]
357    fn as_encode(&self) -> &Self::Encode {
358        self
359    }
360}
361
362impl<'de, A> Decode<'de, Binary, A> for SocketAddrV6
363where
364    A: Allocator,
365{
366    // Not packed since it doesn't have a strongly defined memory layout, even
367    // though it has a particular size.
368    const IS_BITWISE_DECODE: bool = false;
369
370    #[inline]
371    fn decode<D>(decoder: D) -> Result<Self, D::Error>
372    where
373        D: Decoder<'de, Mode = Binary>,
374    {
375        decoder.decode_pack(|p| Ok(Self::new(p.next()?, p.next()?, p.next()?, p.next()?)))
376    }
377}
378
379impl<'de, A> Decode<'de, Text, A> for SocketAddrV6
380where
381    A: Allocator,
382{
383    // Not packed since it doesn't have a strongly defined memory layout, even
384    // though it has a particular size.
385    const IS_BITWISE_DECODE: bool = false;
386
387    #[inline]
388    fn decode<D>(decoder: D) -> Result<Self, D::Error>
389    where
390        D: Decoder<'de>,
391    {
392        let cx = decoder.cx();
393        decoder.decode_unsized(|string: &str| SocketAddrV6::from_str(string).map_err(cx.map()))
394    }
395}
396
397impl<M> Encode<M> for SocketAddr
398where
399    SocketAddrTag: Encode<M>,
400    SocketAddrV4: Encode<M>,
401    SocketAddrV6: Encode<M>,
402{
403    const IS_BITWISE_ENCODE: bool = false;
404
405    #[inline]
406    fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
407    where
408        E: Encoder<Mode = M>,
409    {
410        let variant = encoder.encode_variant()?;
411
412        match self {
413            SocketAddr::V4(v4) => variant.insert_variant(&SocketAddrTag::V4, v4),
414            SocketAddr::V6(v6) => variant.insert_variant(&SocketAddrTag::V6, v6),
415        }
416    }
417
418    type Encode = Self;
419
420    #[inline]
421    fn as_encode(&self) -> &Self::Encode {
422        self
423    }
424}
425
426impl<'de, M, A> Decode<'de, M, A> for SocketAddr
427where
428    A: Allocator,
429    SocketAddrTag: Decode<'de, M, A>,
430    SocketAddrV4: Decode<'de, M, A>,
431    SocketAddrV6: Decode<'de, M, A>,
432{
433    const IS_BITWISE_DECODE: bool = false;
434
435    #[inline]
436    fn decode<D>(decoder: D) -> Result<Self, D::Error>
437    where
438        D: Decoder<'de, Mode = M, Allocator = A>,
439    {
440        decoder.decode_variant(|variant| {
441            let tag = variant.decode_tag()?.decode()?;
442
443            Ok(match tag {
444                SocketAddrTag::V4 => Self::V4(variant.decode_value()?.decode()?),
445                SocketAddrTag::V6 => Self::V6(variant.decode_value()?.decode()?),
446            })
447        })
448    }
449}
450
451#[cfg(test)]
452mod tests {
453    use crate::{Decode, Encode};
454
455    use std::net::{IpAddr, SocketAddr};
456
457    #[derive(Encode, Decode)]
458    #[musli(crate)]
459    #[allow(dead_code)]
460    struct Container {
461        ip_addr: IpAddr,
462        sock_addr: SocketAddr,
463    }
464}