1 use {IpNet, Ipv4Net, Ipv6Net};
2 use std::fmt;
3 use std::net::{Ipv4Addr, Ipv6Addr};
4 use serde::{self, Serialize, Deserialize, Serializer, Deserializer};
5 use serde::ser::{SerializeTuple};
6 use serde::de::{EnumAccess, Error, VariantAccess, Visitor};
7 
8 impl Serialize for IpNet {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer9     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10         where S: Serializer
11     {
12         if serializer.is_human_readable() {
13             match *self {
14                 IpNet::V4(ref a) => a.serialize(serializer),
15                 IpNet::V6(ref a) => a.serialize(serializer),
16             }
17         } else {
18             match *self {
19                 IpNet::V4(ref a) => serializer.serialize_newtype_variant("IpNet", 0, "V4", a),
20                 IpNet::V6(ref a) => serializer.serialize_newtype_variant("IpNet", 1, "V6", a),
21             }
22         }
23     }
24 }
25 
26 impl<'de> Deserialize<'de> for IpNet {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>27     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
28         where D: Deserializer<'de>
29     {
30         if deserializer.is_human_readable() {
31             struct IpNetVisitor;
32 
33             impl<'de> Visitor<'de> for IpNetVisitor {
34                 type Value = IpNet;
35 
36                 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
37                     formatter.write_str("IPv4 or IPv6 network address")
38                 }
39 
40                 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
41                     where E: Error
42                 {
43                     s.parse().map_err(Error::custom)
44                 }
45             }
46 
47             deserializer.deserialize_str(IpNetVisitor)
48         } else {
49             struct EnumVisitor;
50 
51             #[derive(Serialize, Deserialize)]
52             enum IpNetKind {
53                 V4,
54                 V6,
55             }
56 
57             impl<'de> Visitor<'de> for EnumVisitor {
58                 type Value = IpNet;
59 
60                 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
61                     formatter.write_str("IPv4 or IPv6 network address")
62                 }
63 
64                 fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
65                     where A: EnumAccess<'de>
66                 {
67                     match try!(data.variant()) {
68                         (IpNetKind::V4, v) => v.newtype_variant().map(IpNet::V4),
69                         (IpNetKind::V6, v) => v.newtype_variant().map(IpNet::V6),
70                     }
71                 }
72             }
73 
74             deserializer.deserialize_enum("IpNet", &["V4", "V6"], EnumVisitor)
75         }
76     }
77 }
78 
79 impl Serialize for Ipv4Net {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer80     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81         where S: Serializer
82     {
83         if serializer.is_human_readable() {
84             serializer.serialize_str(&self.to_string())
85         } else {
86             let mut seq = serializer.serialize_tuple(5)?;
87             for octet in &self.addr().octets() {
88                 seq.serialize_element(octet)?;
89             }
90             seq.serialize_element(&self.prefix_len())?;
91             seq.end()
92         }
93     }
94 }
95 
96 impl<'de> Deserialize<'de> for Ipv4Net {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>97     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98         where D: Deserializer<'de>
99     {
100         if deserializer.is_human_readable() {
101             struct IpAddrVisitor;
102 
103             impl<'de> Visitor<'de> for IpAddrVisitor {
104                 type Value = Ipv4Net;
105 
106                 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
107                     formatter.write_str("IPv4 network address")
108                 }
109 
110                 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
111                     where E: Error
112                 {
113                     s.parse().map_err(Error::custom)
114                 }
115             }
116 
117             deserializer.deserialize_str(IpAddrVisitor)
118         } else {
119             let b = <[u8; 5]>::deserialize(deserializer)?;
120             Ipv4Net::new(Ipv4Addr::new(b[0], b[1], b[2], b[3]), b[4]).map_err(serde::de::Error::custom)
121         }
122     }
123 }
124 
125 impl Serialize for Ipv6Net {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer126     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
127         where S: Serializer
128     {
129         if serializer.is_human_readable() {
130             serializer.serialize_str(&self.to_string())
131         } else {
132             let mut seq = serializer.serialize_tuple(17)?;
133             for octet in &self.addr().octets() {
134                 seq.serialize_element(octet)?;
135             }
136             seq.serialize_element(&self.prefix_len())?;
137             seq.end()
138         }
139     }
140 }
141 
142 impl<'de> Deserialize<'de> for Ipv6Net {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>143     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
144         where D: Deserializer<'de>
145     {
146         if deserializer.is_human_readable() {
147             struct IpAddrVisitor;
148 
149             impl<'de> Visitor<'de> for IpAddrVisitor {
150                 type Value = Ipv6Net;
151 
152                 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
153                     formatter.write_str("IPv6 network address")
154                 }
155 
156                 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
157                     where E: Error
158                 {
159                     s.parse().map_err(Error::custom)
160                 }
161             }
162 
163             deserializer.deserialize_str(IpAddrVisitor)
164         } else {
165             let b = <[u8; 17]>::deserialize(deserializer)?;
166             Ipv6Net::new(Ipv6Addr::new(
167                 ((b[0] as u16) << 8) | b[1] as u16, ((b[2] as u16) << 8) | b[3] as u16,
168                 ((b[4] as u16) << 8) | b[5] as u16, ((b[6] as u16) << 8) | b[7] as u16,
169                 ((b[8] as u16) << 8) | b[9] as u16, ((b[10] as u16) << 8) | b[11] as u16,
170                 ((b[12] as u16) << 8) | b[13] as u16, ((b[14] as u16) << 8) | b[15] as u16
171             ), b[16]).map_err(Error::custom)
172         }
173     }
174 }
175 
176 #[cfg(test)]
177 mod tests {
178     extern crate serde_test;
179 
180     use {IpNet, Ipv4Net, Ipv6Net};
181     use self::serde_test::{assert_tokens, Configure, Token};
182 
183     #[test]
test_serialize_ipnet_v4()184     fn test_serialize_ipnet_v4() {
185         let net_str = "10.1.1.0/24";
186         let net: IpNet = net_str.parse().unwrap();
187         assert_tokens(&net.readable(), &[Token::Str(net_str)]);
188         assert_tokens(&net.compact(), &[
189             Token::NewtypeVariant { name: "IpNet", variant: "V4", },
190             Token::Tuple { len: 5 },
191             Token::U8(10),
192             Token::U8(1),
193             Token::U8(1),
194             Token::U8(0),
195             Token::U8(24),
196             Token::TupleEnd,
197         ]);
198     }
199 
200     #[test]
test_serialize_ipnet_v6()201     fn test_serialize_ipnet_v6() {
202         let net_str = "fd00::/32";
203         let net: IpNet = net_str.parse().unwrap();
204         assert_tokens(&net.readable(), &[Token::Str(net_str)]);
205         assert_tokens(&net.compact(), &[
206             Token::NewtypeVariant { name: "IpNet", variant: "V6", },
207             // This is too painful, but Token::Bytes() seems to be
208             // an array with a length, which is not what we serialize.
209             Token::Tuple { len: 17 },
210             Token::U8(253u8),
211             Token::U8(0),
212             Token::U8(0),
213             Token::U8(0),
214             Token::U8(0),
215             Token::U8(0),
216             Token::U8(0),
217             Token::U8(0),
218             Token::U8(0),
219             Token::U8(0),
220             Token::U8(0),
221             Token::U8(0),
222             Token::U8(0),
223             Token::U8(0),
224             Token::U8(0),
225             Token::U8(0),
226             Token::U8(32),
227             Token::TupleEnd,
228         ]);
229     }
230 
231     #[test]
test_serialize_ipv4_net()232     fn test_serialize_ipv4_net() {
233         let net_str = "10.1.1.0/24";
234         let net: Ipv4Net = net_str.parse().unwrap();
235         assert_tokens(&net.readable(), &[Token::Str(net_str)]);
236         assert_tokens(&net.compact(), &[
237             Token::Tuple { len: 5 },
238             Token::U8(10),
239             Token::U8(1),
240             Token::U8(1),
241             Token::U8(0),
242             Token::U8(24),
243             Token::TupleEnd,
244         ]);
245     }
246 
247     #[test]
test_serialize_ipv6_net()248     fn test_serialize_ipv6_net() {
249         let net_str = "fd00::/32";
250         let net: Ipv6Net = net_str.parse().unwrap();
251         assert_tokens(&net.readable(), &[Token::Str(net_str)]);
252         assert_tokens(&net.compact(), &[
253             // This is too painful, but Token::Bytes() seems to be
254             // an array with a length, which is not what we serialize.
255             Token::Tuple { len: 17 },
256             Token::U8(253u8),
257             Token::U8(0),
258             Token::U8(0),
259             Token::U8(0),
260             Token::U8(0),
261             Token::U8(0),
262             Token::U8(0),
263             Token::U8(0),
264             Token::U8(0),
265             Token::U8(0),
266             Token::U8(0),
267             Token::U8(0),
268             Token::U8(0),
269             Token::U8(0),
270             Token::U8(0),
271             Token::U8(0),
272             Token::U8(32),
273             Token::TupleEnd,
274         ]);
275     }
276 }