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 { 9 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 { 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 { 80 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 { 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 { 126 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 { 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] 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] 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] 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] 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 }