mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 03:11:02 +00:00
Add non-human readable serializations for ip addresses
This commit is contained in:
+85
-10
@@ -868,38 +868,113 @@ map_impl!(
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
macro_rules! count {
|
||||||
|
() => {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
($first: expr $(,$rest: expr)*) => {
|
||||||
|
1 + count!($($rest),*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
macro_rules! parse_impl {
|
macro_rules! parse_ip_impl {
|
||||||
($ty:ty) => {
|
($ty:ty; $($size: expr),*) => {
|
||||||
impl<'de> Deserialize<'de> for $ty {
|
impl<'de> Deserialize<'de> for $ty {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let s = try!(String::deserialize(deserializer));
|
struct ParseVisitor;
|
||||||
s.parse().map_err(Error::custom)
|
impl<'de> Visitor<'de> for ParseVisitor {
|
||||||
|
type Value = $ty;
|
||||||
|
|
||||||
|
#[allow(unused_assignments)]
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(formatter, "Expected bytes of length ")?;
|
||||||
|
let mut i = 0;
|
||||||
|
$(
|
||||||
|
let sep = match i {
|
||||||
|
0 => "",
|
||||||
|
_ if i + 1 == count!($size) => " or ",
|
||||||
|
_ => ", ",
|
||||||
|
};
|
||||||
|
write!(formatter, "{}{}", sep, $size)?;
|
||||||
|
i += 1;
|
||||||
|
)*
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, value: &str) -> Result<$ty, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
value.parse().map_err(Error::custom)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, value: &[u8]) -> Result<$ty, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
match value.len() {
|
||||||
|
$(
|
||||||
|
$size => {
|
||||||
|
let mut buffer = [0; $size];
|
||||||
|
buffer.copy_from_slice(value);
|
||||||
|
Ok(<$ty>::from(buffer))
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
_ => Err(Error::invalid_length(value.len(), &self)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deserializer.is_human_readable() {
|
||||||
|
let s = try!(String::deserialize(deserializer));
|
||||||
|
s.parse().map_err(Error::custom)
|
||||||
|
} else {
|
||||||
|
deserializer.deserialize_bytes(ParseVisitor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
parse_impl!(net::IpAddr);
|
parse_ip_impl!(net::IpAddr; 16, 4);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
parse_impl!(net::Ipv4Addr);
|
parse_ip_impl!(net::Ipv4Addr; 4);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
parse_impl!(net::Ipv6Addr);
|
parse_ip_impl!(net::Ipv6Addr; 16);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
parse_impl!(net::SocketAddr);
|
macro_rules! parse_socket_impl {
|
||||||
|
($ty:ty, $new: expr) => {
|
||||||
|
impl<'de> Deserialize<'de> for $ty {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
if deserializer.is_human_readable() {
|
||||||
|
let s = try!(String::deserialize(deserializer));
|
||||||
|
s.parse().map_err(Error::custom)
|
||||||
|
} else {
|
||||||
|
<(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
parse_impl!(net::SocketAddrV4);
|
parse_socket_impl!(net::SocketAddr, net::SocketAddr::new);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
parse_impl!(net::SocketAddrV6);
|
parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(ip, port, 0, 0));
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
+28
-12
@@ -519,9 +519,13 @@ impl Serialize for net::Ipv4Addr {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
/// "101.102.103.104".len()
|
if serializer.is_human_readable() {
|
||||||
const MAX_LEN: usize = 15;
|
/// "101.102.103.104".len()
|
||||||
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
const MAX_LEN: usize = 15;
|
||||||
|
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
||||||
|
} else {
|
||||||
|
self.octets().serialize(serializer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,9 +535,13 @@ impl Serialize for net::Ipv6Addr {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
/// "1000:1002:1003:1004:1005:1006:1007:1008".len()
|
if serializer.is_human_readable() {
|
||||||
const MAX_LEN: usize = 39;
|
/// "1000:1002:1003:1004:1005:1006:1007:1008".len()
|
||||||
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
const MAX_LEN: usize = 39;
|
||||||
|
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
||||||
|
} else {
|
||||||
|
self.octets().serialize(serializer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,9 +564,13 @@ impl Serialize for net::SocketAddrV4 {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
/// "101.102.103.104:65000".len()
|
if serializer.is_human_readable() {
|
||||||
const MAX_LEN: usize = 21;
|
/// "101.102.103.104:65000".len()
|
||||||
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
const MAX_LEN: usize = 21;
|
||||||
|
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
||||||
|
} else {
|
||||||
|
(self.ip().octets(), self.port()).serialize(serializer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,9 +580,13 @@ impl Serialize for net::SocketAddrV6 {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
/// "[1000:1002:1003:1004:1005:1006:1007:1008]:65000".len()
|
if serializer.is_human_readable() {
|
||||||
const MAX_LEN: usize = 47;
|
/// "[1000:1002:1003:1004:1005:1006:1007:1008]:65000".len()
|
||||||
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
const MAX_LEN: usize = 47;
|
||||||
|
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
||||||
|
} else {
|
||||||
|
(self.ip().octets(), self.port()).serialize(serializer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user