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}