From 99d9151ce97a01db214ff21ead6548e5d0150cfa Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Tue, 12 Jan 2021 11:31:37 +0100 Subject: [PATCH 1/2] refactor: Merge multiple FromStr visitors to a single FromStrVisitor Only refactors, doesn't actually expose this visitor --- serde/src/de/impls.rs | 106 ++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 71 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index d9af210e..d507de6b 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1260,24 +1260,7 @@ macro_rules! parse_ip_impl { D: Deserializer<'de>, { if deserializer.is_human_readable() { - struct IpAddrVisitor; - - impl<'de> Visitor<'de> for IpAddrVisitor { - type Value = $ty; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str($expecting) - } - - fn visit_str(self, s: &str) -> Result - where - E: Error, - { - s.parse().map_err(Error::custom) - } - } - - deserializer.deserialize_str(IpAddrVisitor) + deserializer.deserialize_str(FromStrVisitor::<$ty>::new($expecting)) } else { <[u8; $size]>::deserialize(deserializer).map(<$ty>::from) } @@ -1405,24 +1388,7 @@ impl<'de> Deserialize<'de> for net::IpAddr { D: Deserializer<'de>, { if deserializer.is_human_readable() { - struct IpAddrVisitor; - - impl<'de> Visitor<'de> for IpAddrVisitor { - type Value = net::IpAddr; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("IP address") - } - - fn visit_str(self, s: &str) -> Result - where - E: Error, - { - s.parse().map_err(Error::custom) - } - } - - deserializer.deserialize_str(IpAddrVisitor) + deserializer.deserialize_str(FromStrVisitor::new("IP address")) } else { use lib::net::IpAddr; deserialize_enum! { @@ -1449,24 +1415,7 @@ macro_rules! parse_socket_impl { D: Deserializer<'de>, { if deserializer.is_human_readable() { - struct SocketAddrVisitor; - - impl<'de> Visitor<'de> for SocketAddrVisitor { - type Value = $ty; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str($expecting) - } - - fn visit_str(self, s: &str) -> Result - where - E: Error, - { - s.parse().map_err(Error::custom) - } - } - - deserializer.deserialize_str(SocketAddrVisitor) + deserializer.deserialize_str(FromStrVisitor::<$ty>::new($expecting)) } else { <(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port)) } @@ -1482,24 +1431,8 @@ impl<'de> Deserialize<'de> for net::SocketAddr { D: Deserializer<'de>, { if deserializer.is_human_readable() { - struct SocketAddrVisitor; - impl<'de> Visitor<'de> for SocketAddrVisitor { - type Value = net::SocketAddr; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("socket address") - } - - fn visit_str(self, s: &str) -> Result - where - E: Error, - { - s.parse().map_err(Error::custom) - } - } - - deserializer.deserialize_str(SocketAddrVisitor) + deserializer.deserialize_str(FromStrVisitor::new("socket address")) } else { use lib::net::SocketAddr; deserialize_enum! { @@ -2603,3 +2536,34 @@ atomic_impl! { atomic_impl! { AtomicI64 AtomicU64 } + + +#[cfg(feature = "std")] +struct FromStrVisitor(&'static str, PhantomData); + +#[cfg(feature = "std")] +impl FromStrVisitor { + fn new(msg: &'static str) -> Self { + FromStrVisitor(msg, PhantomData) + } +} + +#[cfg(feature = "std")] +impl<'de, T> Visitor<'de> for FromStrVisitor +where + T: str::FromStr, + T::Err: fmt::Display, +{ + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.0) + } + + fn visit_str(self, s: &str) -> Result + where + E: Error, + { + s.parse().map_err(Error::custom) + } +} From 391d3ababf5e329777571c8fe03117d8bbba8d40 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 12 Jan 2021 13:02:53 -0800 Subject: [PATCH 2/2] Touch up PR 1948 --- serde/src/de/impls.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index d507de6b..66c14659 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1260,7 +1260,7 @@ macro_rules! parse_ip_impl { D: Deserializer<'de>, { if deserializer.is_human_readable() { - deserializer.deserialize_str(FromStrVisitor::<$ty>::new($expecting)) + deserializer.deserialize_str(FromStrVisitor::new($expecting)) } else { <[u8; $size]>::deserialize(deserializer).map(<$ty>::from) } @@ -1415,7 +1415,7 @@ macro_rules! parse_socket_impl { D: Deserializer<'de>, { if deserializer.is_human_readable() { - deserializer.deserialize_str(FromStrVisitor::<$ty>::new($expecting)) + deserializer.deserialize_str(FromStrVisitor::new($expecting)) } else { <(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port)) } @@ -1431,7 +1431,6 @@ impl<'de> Deserialize<'de> for net::SocketAddr { D: Deserializer<'de>, { if deserializer.is_human_readable() { - deserializer.deserialize_str(FromStrVisitor::new("socket address")) } else { use lib::net::SocketAddr; @@ -2537,14 +2536,19 @@ atomic_impl! { AtomicI64 AtomicU64 } - #[cfg(feature = "std")] -struct FromStrVisitor(&'static str, PhantomData); +struct FromStrVisitor { + expecting: &'static str, + ty: PhantomData, +} #[cfg(feature = "std")] impl FromStrVisitor { - fn new(msg: &'static str) -> Self { - FromStrVisitor(msg, PhantomData) + fn new(expecting: &'static str) -> Self { + FromStrVisitor { + expecting: expecting, + ty: PhantomData, + } } } @@ -2557,7 +2561,7 @@ where type Value = T; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str(self.0) + formatter.write_str(self.expecting) } fn visit_str(self, s: &str) -> Result