musli_core/impls/
net.rs

1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
2use std::str::FromStr;
3
4use crate::context::Context;
5use crate::de::{Decode, Decoder, SequenceDecoder, VariantDecoder};
6use crate::en::{Encode, Encoder, SequenceEncoder, VariantEncoder};
7use crate::mode::{Binary, Text};
8
9#[derive(Encode, Decode)]
10#[musli(crate)]
11#[musli(mode = Text, name_all = "kebab-case")]
12enum IpAddrTag {
13    Ipv4,
14    Ipv6,
15}
16
17#[derive(Encode, Decode)]
18#[musli(crate)]
19#[musli(mode = Text, name_all = "kebab-case")]
20enum SocketAddrTag {
21    V4,
22    V6,
23}
24
25impl Encode<Binary> for Ipv4Addr {
26    #[inline]
27    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
28    where
29        E: Encoder,
30    {
31        encoder.encode_array(&self.octets())
32    }
33}
34
35impl Encode<Text> for Ipv4Addr {
36    #[inline]
37    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
38    where
39        E: Encoder,
40    {
41        encoder.collect_string(self)
42    }
43}
44
45impl<'de> Decode<'de, Binary> for Ipv4Addr {
46    #[inline]
47    fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
48    where
49        D: Decoder<'de>,
50    {
51        decoder.decode_array::<4>().map(Ipv4Addr::from)
52    }
53}
54
55impl<'de> Decode<'de, Text> for Ipv4Addr {
56    #[inline]
57    fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
58    where
59        D: Decoder<'de>,
60    {
61        decoder.decode_unsized(|string: &str| Ipv4Addr::from_str(string).map_err(cx.map()))
62    }
63}
64
65impl Encode<Binary> for Ipv6Addr {
66    #[inline]
67    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
68    where
69        E: Encoder<Mode = Binary>,
70    {
71        encoder.encode_array(&self.octets())
72    }
73}
74
75impl Encode<Text> for Ipv6Addr {
76    #[inline]
77    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
78    where
79        E: Encoder<Mode = Text>,
80    {
81        encoder.collect_string(self)
82    }
83}
84
85impl<'de> Decode<'de, Binary> for Ipv6Addr {
86    #[inline]
87    fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
88    where
89        D: Decoder<'de>,
90    {
91        decoder.decode_array::<16>().map(Ipv6Addr::from)
92    }
93}
94
95impl<'de> Decode<'de, Text> for Ipv6Addr {
96    #[inline]
97    fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
98    where
99        D: Decoder<'de>,
100    {
101        decoder.decode_unsized(|string: &str| Ipv6Addr::from_str(string).map_err(cx.map()))
102    }
103}
104
105impl<M> Encode<M> for IpAddr
106where
107    IpAddrTag: Encode<M>,
108    Ipv4Addr: Encode<M>,
109    Ipv6Addr: Encode<M>,
110{
111    #[inline]
112    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
113    where
114        E: Encoder<Mode = M>,
115    {
116        let variant = encoder.encode_variant()?;
117
118        match self {
119            IpAddr::V4(v4) => variant.insert_variant(IpAddrTag::Ipv4, v4),
120            IpAddr::V6(v6) => variant.insert_variant(IpAddrTag::Ipv6, v6),
121        }
122    }
123}
124
125impl<'de, M> Decode<'de, M> for IpAddr
126where
127    IpAddrTag: Decode<'de, M>,
128    Ipv4Addr: Decode<'de, M>,
129    Ipv6Addr: Decode<'de, M>,
130{
131    #[inline]
132    fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
133    where
134        D: Decoder<'de, Mode = M>,
135    {
136        decoder.decode_variant(|variant| {
137            let tag = variant.decode_tag()?.decode()?;
138
139            Ok(match tag {
140                IpAddrTag::Ipv4 => Self::V4(variant.decode_value()?.decode()?),
141                IpAddrTag::Ipv6 => Self::V6(variant.decode_value()?.decode()?),
142            })
143        })
144    }
145}
146
147impl Encode<Binary> for SocketAddrV4 {
148    #[inline]
149    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
150    where
151        E: Encoder<Mode = Binary>,
152    {
153        encoder.encode_pack_fn(|pack| {
154            pack.push(self.ip())?;
155            pack.push(self.port())?;
156            Ok(())
157        })
158    }
159}
160
161impl Encode<Text> for SocketAddrV4 {
162    #[inline]
163    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
164    where
165        E: Encoder<Mode = Text>,
166    {
167        encoder.collect_string(self)
168    }
169}
170
171impl<'de> Decode<'de, Binary> for SocketAddrV4 {
172    #[inline]
173    fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
174    where
175        D: Decoder<'de, Mode = Binary>,
176    {
177        decoder.decode_pack(|p| Ok(SocketAddrV4::new(p.next()?, p.next()?)))
178    }
179}
180
181impl<'de> Decode<'de, Text> for SocketAddrV4 {
182    #[inline]
183    fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
184    where
185        D: Decoder<'de>,
186    {
187        decoder.decode_unsized(|string: &str| SocketAddrV4::from_str(string).map_err(cx.map()))
188    }
189}
190
191impl Encode<Binary> for SocketAddrV6 {
192    #[inline]
193    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
194    where
195        E: Encoder<Mode = Binary>,
196    {
197        encoder.encode_pack_fn(|pack| {
198            pack.push(self.ip())?;
199            pack.push(self.port())?;
200            pack.push(self.flowinfo())?;
201            pack.push(self.scope_id())?;
202            Ok(())
203        })
204    }
205}
206
207impl Encode<Text> for SocketAddrV6 {
208    #[inline]
209    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
210    where
211        E: Encoder<Mode = Text>,
212    {
213        encoder.collect_string(self)
214    }
215}
216
217impl<'de> Decode<'de, Binary> for SocketAddrV6 {
218    #[inline]
219    fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
220    where
221        D: Decoder<'de, Mode = Binary>,
222    {
223        decoder.decode_pack(|p| Ok(Self::new(p.next()?, p.next()?, p.next()?, p.next()?)))
224    }
225}
226
227impl<'de> Decode<'de, Text> for SocketAddrV6 {
228    #[inline]
229    fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
230    where
231        D: Decoder<'de>,
232    {
233        decoder.decode_unsized(|string: &str| SocketAddrV6::from_str(string).map_err(cx.map()))
234    }
235}
236
237impl<M> Encode<M> for SocketAddr
238where
239    SocketAddrTag: Encode<M>,
240    SocketAddrV4: Encode<M>,
241    SocketAddrV6: Encode<M>,
242{
243    #[inline]
244    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
245    where
246        E: Encoder<Mode = M>,
247    {
248        let variant = encoder.encode_variant()?;
249
250        match self {
251            SocketAddr::V4(v4) => variant.insert_variant(SocketAddrTag::V4, v4),
252            SocketAddr::V6(v6) => variant.insert_variant(SocketAddrTag::V6, v6),
253        }
254    }
255}
256
257impl<'de, M> Decode<'de, M> for SocketAddr
258where
259    SocketAddrTag: Decode<'de, M>,
260    SocketAddrV4: Decode<'de, M>,
261    SocketAddrV6: Decode<'de, M>,
262{
263    #[inline]
264    fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
265    where
266        D: Decoder<'de, Mode = M>,
267    {
268        decoder.decode_variant(|variant| {
269            let tag = variant.decode_tag()?.decode()?;
270
271            Ok(match tag {
272                SocketAddrTag::V4 => Self::V4(variant.decode_value()?.decode()?),
273                SocketAddrTag::V6 => Self::V6(variant.decode_value()?.decode()?),
274            })
275        })
276    }
277}
278
279#[cfg(test)]
280mod tests {
281    use crate::{Decode, Encode};
282
283    use std::net::{IpAddr, SocketAddr};
284
285    #[derive(Encode, Decode)]
286    #[musli(crate)]
287    #[allow(dead_code)]
288    struct Container {
289        ip_addr: IpAddr,
290        sock_addr: SocketAddr,
291    }
292}