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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}